2010-10-01 13 views
5

Sto riscontrando qualche problema con l'aggiornamento della raccolta correlata di entità.Entity Framework POCO: aggiorna una proprietà di navigazione

In sostanza il problema è il seguente:

public class Student 
{ 
    public virtual ICollection<Lecture> Lectures { get; set; } 

    public void AddLecture(Lecture lecture) 
    { 
     Lectures.Add(lecture); 
    } 

    public void CancelChanges() 
    { 
     _context.Refresh(RefreshMode.StoreWins, this); 
     _context.LoadProperty(this, (o) => o.Lectures, 
      MergeOption.OverwriteChanges); 
    } 
} 

public class Grade 
{ 
    public virtual Student { get; set; } 
} 

Ora ho un po 'interfaccia grafica per l'aggiunta di lezioni e, se vogliamo possiamo annullare il processo di editing:

public void ExampleEdit() 
{ 
    Student student = _context.Students.SingleOrDefault(/* blah */); 
    student.AddLecture(_context.Lectures.SingleOrDefault(/* e.g. math */)); 
    student.CancelChanges(); 
    // At this point student SHOULD have no lectures anymore since the 
    // property was loaded with overwrite changes option. 
    // Yet the Lectures still contains the lecture we added there 
} 

Quindi, è il codice cattivo? C'è qualche metodo che uso in modo errato? È possibile COMPLETAMENTE ricaricare l'intero oggetto? ..

risposta

7

Penso che abbia frainteso MergeOption.OverwriteChanges. Per impostazione predefinita, ogni volta che l'oggetto ObjectContext esegue una query, se uno qualsiasi degli oggetti restituiti esiste già nella cache, le copie appena restituite di tali oggetti vengono ignorate.

Si noti che tutto avviene in base alle EntityKeys. Fondamentalmente le EntityKeys degli oggetti restituiti da una query sono controllati, e se un oggetto con il stesso EntityKey (nello stesso EntitySet, nel caso, Lectures) esiste già nella cache, l'oggetto esistente è lasciato intatto.

Tuttavia, se si attiva OverwriteChanges, allora sarà Sostituire i valori attuali delle entità esistenti con i valori provenienti dal database, anche se l'entità in memoria è stato modificato.

Come si può vedere si sta aggiungendo una conferenza allo studente che è totalmente nuovo per studenti e non sarà sovrascritto dal suo EntityKey è diverso da quelli che provenienti dalla banca dati secondo il vostro LoadProperty() chiamata.

Una soluzione potrebbe essere quella di semplicemente chiare tutte le lezioni dal vostro oggetto studente poco prima LoadProperty():

public void CancelChanges() { 
    _context.Refresh(RefreshMode.StoreWins, this); 
    this.Lectures.Clear(); 
    _context.LoadProperty(this, (o) => o.Lectures, MergeOption.OverwriteChanges); 
} 
+0

Grazie mille per la spiegazione - ha fatto un sacco di cose molto più chiare nella mia testa. E la soluzione che hai proposto è molto utile: ho appena aggiornato il mio codice e la cosa funziona davvero. – Jefim

+0

Siete i benvenuti, sono contento che abbia aiutato :) –

Problemi correlati