2010-10-01 11 views
5

Mam problem z odświeżeniem pokrewnego zbioru obiektów.Entity Framework POCO - Odśwież właściwość nawigacji

Zasadniczo problem jest następujący:

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; } 
} 

Teraz mam jakieś GUI do dodawania wykłady, a jeśli chcemy możemy anulować proces edycji:

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 
} 

Tak, to kod zły? Czy istnieje metoda, której używam nieprawidłowo? Czy jest możliwe CAŁKOWICIE przeładować cały obiekt? ..

Odpowiedz

7

Myślę, że źle zrozumiałeś MergeOption.OverwriteChanges. Domyślnie w dowolnym momencie ObjectContext wykonuje zapytanie, jeśli którykolwiek z zwróconych obiektów już istnieje w pamięci podręcznej, nowo zwrócone kopie tych obiektów są ignorowane.
Należy pamiętać, że wszystko dzieje się w oparciu o EntityKeys. Zasadniczo EntityKeys obiektów zwrócony z kwerendy są sprawdzane, a jeśli obiekt z samym EntityKey (w tym samym EntitySet, w danym przypadku, Wykłady) już istnieje w pamięci podręcznej, istniejący obiekt pozostaje nietknięty.

Jednak jeśli włączysz OverwriteChanges, to będzie Wymień bieżące wartości istniejących podmiotów o wartościach pochodzących z bazy danych, nawet jeśli jednostka w pamięci został edytowany.

Jak widać dodawania wykład dla studenta, który jest całkowicie nowy na studenta i nie zostaną nadpisane, ponieważ jego EntityKey jest inna niż te, które pochodzących z bazy danych, jak na swój LoadProperty() połączeń.

Jednym rozwiązaniem byłoby po prostu zaznaczenie wszystkich Wykłady z Twojego obiektu studentów tuż przed LoadProperty():

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

dziękuję za wyjaśnienie - to uczynił wiele rzeczy dużo jaśniejszych w mojej głowie. Proponowane przez ciebie rozwiązanie jest bardzo przydatne - po prostu zaktualizowałem swój kod i rzeczy naprawdę działają. – Jefim

+0

Bardzo proszę, cieszę się, że pomogło :) –

Powiązane problemy