Entity framework 实体框架POCO-刷新导航属性

Entity framework 实体框架POCO-刷新导航属性,entity-framework,poco,navigation-properties,Entity Framework,Poco,Navigation Properties,我在刷新实体的相关集合时遇到一些问题 基本上,问题如下: public class Student { public virtual ICollection<Lecture> Lectures { get; set; } public void AddLecture(Lecture lecture) { Lectures.Add(lecture); } public void CancelChanges() {

我在刷新实体的相关集合时遇到一些问题

基本上,问题如下:

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; }
}
那么,代码是坏的吗?有没有什么方法我用错了?是否可以完全重新加载整个对象?。

我认为您误解了MergeOption.OverwriteChanges。默认情况下,只要ObjectContext执行查询,如果缓存中已经存在任何返回的对象,则忽略这些对象的新返回副本。

请注意,这一切都是基于实体键进行的。基本上,检查查询返回的对象的EntityKey,如果缓存中已经存在具有相同EntityKey的对象(在同一EntitySet中,在您的例子中是TEACHESS),则现有对象保持不变。

但是,如果启用,则它将用来自数据库的值替换现有实体的当前值,即使内存中的实体已被编辑。

正如您所看到的,您正在向学生添加一个对学生来说是全新的讲座,它不会被覆盖,因为它的EntityKey不同于根据LoadProperty()调用从数据库中获取的EntityKey。

一种解决方案是在LoadProperty()之前简单地清除student对象中的所有讲座:


非常感谢你的解释,它让我的头脑中的很多事情都变得清晰了。您提出的解决方案非常方便-我刚刚更新了代码,这件事实际上是可行的。
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
}
public void CancelChanges() {
    _context.Refresh(RefreshMode.StoreWins, this);
    this.Lectures.Clear();
    _context.LoadProperty(this, (o) => o.Lectures, MergeOption.OverwriteChanges);
}