2010-10-01 21 views
5

Tengo problemas para actualizar la colección relacionada de entidades.Entity Framework POCO - Actualizar una propiedad de navegación

En esencia, el problema es el siguiente:

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

Ahora tengo algo de interfaz gráfica de usuario para la adición de conferencias y, si queremos, podemos cancelar el proceso de edición:

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 
} 

Por lo tanto, es el código ¿malo? ¿Hay algún método que use incorrectamente? ¿Es posible COMPLETAMENTE volver a cargar todo el objeto? ..

Respuesta

7

Creo que malentendió MergeOption.OverwriteChanges. De forma predeterminada, cada vez que ObjectContext realiza una consulta, si alguno de los objetos devueltos ya existe en la memoria caché, se ignoran las copias de esos objetos devueltas recientemente.

Tenga en cuenta que todo sucede según el EntityKeys. Básicamente los EntityKeys de los objetos devueltos por una consulta se comprueban, y si un objeto con el misma EntityKey (en la misma EntitySet, en su caso, Conferencias) ya existe en la memoria caché, el objeto existente se deja intacto

Sin embargo, si se habilita OverwriteChanges, a continuación, se Reemplazar los valores actuales de las entidades existentes con los valores procedentes de la base de datos, incluso si la entidad en memoria ha sido editado.

Como se puede ver que está agregando una conferencia a los estudiantes que es totalmente nueva con el estudiante y no se sobrescribirá desde su EntityKey es diferente a los que vienen de la base de datos como por su LoadProperty() llamada.

Una solución sería simplemente claras todas las conferencias de su objeto de estudiante justo antes LoadProperty():

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

Gracias mucho por la explicación - se ha hecho un montón de cosas mucho más claras en mi cabeza. Y la solución que propusiste es muy útil: acabo de actualizar mi código y la cosa realmente funciona. – Jefim

+0

Eres bienvenido, me alegro de que haya sido útil :) –

Cuestiones relacionadas