EF4 -不可能在同一上下文中从不同对象更新同一表行两次
本文关键字:两次 更新 不可能 上下文 EF4 对象 | 更新日期: 2023-09-27 17:55:02
当我在同一上下文中两次收到相同的表行更新时,我得到:
"AcceptChanges不能继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges "
之前确保键值是唯一的。问题发生在ChangeState方法。
我所拥有的可以简化为:
var obj1 = new test() { id = 1,name = "oiu"};
var dc = Context.Create();
dc.test.AddObject(obj1);
if (dc.test.Any(a => a.id == obj1.id))
dc.ObjectStateManager.GetObjectStateEntry(obj1).ChangeState(EntityState.Modified);
dc.SaveChanges();
//---- another iteration of the reading thread, another object, but same context:
var obj2 = new test() { id = 1, name = "ois" };
dc.test.AddObject(obj2);
if (dc.test.Any(a => a.id == obj2.id))
dc.ObjectStateManager.GetObjectStateEntry(obj2).ChangeState(EntityState.Modified);
dc.SaveChanges();
有出路吗?
那么,你想做什么呢?您已经告诉EF和数据库(我假设)"id"是对象/行的唯一标识符。然后,你告诉它你想要添加两个具有相同唯一id("1")的对象,并期望它处理工作。
您是想添加具有相同唯一ID的对象,还是想添加一个,然后更新现有的行/对象,将name属性从"oiu"更改为"ois"。如果是前者,不要把"id"变成pkid。如果是后者,不要告诉EF您想要添加对象两次。添加一次,更新现有对象。
您只能将对象连接到上下文一次(通过从数据库加载对象或调用Attach
或AddObject
)。一旦将对象连接到上下文,您就有责任为所有修改使用相同的实例。上下文使用身份映射模式——这意味着它通过对象的唯一标识(基于主键和实体集的实体键)来跟踪对象,并且只允许具有给定实体键的类型的一个实例。唯一的例外是添加新对象,其中EntityKey
是临时的,直到保存更改,但如果您将状态更改为Modified
,则不是这样。
如果您不知道测试中其余部分的实例,您可以查询ObjectStateManager.GetObjectStateEntries
并搜索您的实例(每个条目都有引用实例的Entity
属性)。