[英]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.