EF4 - 在不同对象的相同上下文中两次更新同一个表行?

时间:2011-05-05 03:02:41

标签: c# entity-framework entity-framework-4

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

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

有出路吗?

2 个答案:

答案 0 :(得分:1)

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

是否要添加具有相同唯一ID的对象,或者是否要添加一个,然后更新现有行/对象以将名称属性从“oiu”更改为“ois”。如果是前者,请不要将“id”变成pkid。如果是后者,请不要告诉EF你想要两次添加对象。添加一次,更新现有对象。

答案 1 :(得分:0)

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

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