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

C# EF4-不可能在同一上下文中从不同对象更新同一表行两次?,c#,entity-framework,entity-framework-4,C#,Entity Framework,Entity Framework 4,当我在同一上下文中两次收到相同的表行进行更新时,我得到: “AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用AcceptChanges之前,请确保键值是唯一的。” 问题发生在ChangeState方法中 我所拥有的可以简化为: var obj1 = new test() { id = 1,name = "oiu"}; var dc = Context.Create(); dc.te

当我在同一上下文中两次收到相同的表行进行更新时,我得到:

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
并搜索实例(每个条目都有引用实例的
实体
属性)。

在这两种情况下,我实际上都在更新。我的争吵从一开始就在那里。在这两种情况下,我都将状态更改为“修改”。感谢您为Ladislav指路。事实上,在测试的其余部分,我不知道该实例,并且能够通过GetObjectStateEntries找到它。完成此操作后,我看到的唯一能够根据需要使用obj2修改表行的选项是首先分离obj1。如果是这样,我最好的选择是始终附加对象、修改ChangeState、保存更改和分离。