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();

有出路吗?

EF4 -不可能在同一上下文中从不同对象更新同一表行两次

那么,你想做什么呢?您已经告诉EF和数据库(我假设)"id"是对象/行的唯一标识符。然后,你告诉它你想要添加两个具有相同唯一id("1")的对象,并期望它处理工作。

您是想添加具有相同唯一ID的对象,还是想添加一个,然后更新现有的行/对象,将name属性从"oiu"更改为"ois"。如果是前者,不要把"id"变成pkid。如果是后者,不要告诉EF您想要添加对象两次。添加一次,更新现有对象。

您只能将对象连接到上下文一次(通过从数据库加载对象或调用AttachAddObject)。一旦将对象连接到上下文,您就有责任为所有修改使用相同的实例。上下文使用身份映射模式——这意味着它通过对象的唯一标识(基于主键和实体集的实体键)来跟踪对象,并且只允许具有给定实体键的类型的一个实例。唯一的例外是添加新对象,其中EntityKey是临时的,直到保存更改,但如果您将状态更改为Modified,则不是这样。

如果您不知道测试中其余部分的实例,您可以查询ObjectStateManager.GetObjectStateEntries并搜索您的实例(每个条目都有引用实例的Entity属性)。