繁体   English   中英

实体框架保存对集合的更改

[英]Entity Framework Save changes on Collection

我有这段代码

public int Update(Item item)
{
    using (var ctx = new DataConext())
    {
        ctx.Entry(item).State = EntityState.Modified;
        return ctx.SaveChanges();
    }
}

Class Item
{
 public string Name {get;set;}
 public ICollection<Foobar> Foos {get;set;}
}

Class Foobar
{
 public string FirstName {get;set;}
 public string LastName {get;set;}
}

让我们说:

item.Foos.ElementAt(0).FirstName = "edited name"

SaveChanged() 已执行,但我在数据库中有“旧”值而不是“已编辑名称”...

我可以在调试中看到本地的正确更改。

看起来您的对象来自与您现在使用的不同的上下文。 在那种情况下,您不能使用泛型来做到这一点,因为您需要在 Foobar 集合中执行 forEach 并分别更改每个项目的状态。

你这里有一个断开连接的实体图,因此实体断开连接并且更改跟踪丢失。 您只需设置主要实体的状态,因此 EF 假定其他所有内容均未更改。

Jullie Lerman 的书是了解其工作原理的好资源

我要做的是为简单实体保留此方法,但将其设为虚拟,以便您可以继承此存储库以创建特定的实体存储库,并使用更适合实体的更新方法覆盖更新方法,例如示例中的实体。

一篇帮助我设计这样一个回购协议的文章是这样的: http ://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the -asp-net-mvc-application 中的存储库和工作单元模式

您正在将对象加载到上下文中并保存在另一个上下文中。 删除using (var ctx = new DataConext())块,并搜索一种方法来访问加载项目的上下文,然后调用SaveChanges(); 另一种方法是将上下文传递给方法,例如public int Update(Item item, DbContext context)并保存更改。

Class Item
{
    public string Name {get;set;}
    public ICollection<Foobar> Foos {get;set;}
}

您需要Include将 Foos 包含到对象管理器中。 现在,它正在加载。 无论您在哪里加载项目,都必须包含它。

您应该使用include ,或者您可以使用virtual让它们延迟加载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM