2010-10-01 25 views
5

Je rencontre des problèmes avec l'actualisation de la collection d'entités associée.Entity Framework POCO - Actualiser une propriété de navigation

Essentiellement, le problème est la suivante:

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

Maintenant, j'ai une interface graphique pour ajouter des conférences et, si nous voulons nous pouvons annuler le processus d'édition:

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 
} 

Ainsi, le code mal? Y a-t-il une méthode que j'utilise incorrectement? Est-il possible de recharger COMPLÈTEMENT l'objet entier? ..

Répondre

7

Je pense que vous avez mal compris MergeOption.OverwriteChanges. Par défaut, à chaque fois que ObjectContext exécute une requête, si l'un des objets renvoyés existe déjà dans le cache, les copies nouvellement retournées de ces objets sont ignorées.

S'il vous plaît noter que tout cela se produit sur la EntityKeys. Fondamentalement, les EntityKeys des objets renvoyés d'une requête sont vérifiées, et si un objet avec le même EntityKey (dans le même EntitySet, dans votre cas, conférences) existe déjà dans le cache, l'objet existant est laissé intacte.

Toutefois, si vous activez OverwriteChanges, il sera Remplacer les valeurs actuelles des entités existantes avec des valeurs provenant de la base de données, même si l'entité en mémoire a été modifié.

Comme vous pouvez le voir vous ajoutez une conférence à l'étudiant qui est totalement nouveau pour l'élève et il ne sera pas écrasé depuis son EntityKey est différent de ceux qui viennent de la base de données selon votre LoadProperty() appel.

Une solution serait tout simplement effacer toutes les conférences de votre objet étudiant juste avant LoadProperty():

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

Merci beaucoup pour l'explication - il a fait beaucoup de choses beaucoup plus claires dans ma tête. Et la solution que vous avez proposée est très pratique - je viens de mettre à jour mon code et la chose fonctionne réellement. – Jefim

+0

Vous êtes les bienvenus, je suis content que cela ait aidé :) –