EF4 - 在同一上下文中从不同对象更新同一表行两次不可能吗?
当我在同一上下文中两次收到相同的表行更新时,我得到:
“AcceptChanges 无法继续,因为该对象的键值与 ObjectStateManager 中的另一个对象冲突。在调用 AcceptChanges 之前,请确保键值是唯一的。< /strong>”
问题发生在 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();
有没有出路或绕过?
When I receive the same table row twice for updating in the same context I get:
"AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges."
The problem happens at the ChangeState method.
What I have can be simplified to this:
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();
Is there a way out or around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
那么,你想做什么?您已经告诉 EF 和数据库(我假设)“id”是对象/行的唯一标识符。然后,您告诉它您想要添加两个具有相同唯一 id(“1”)的对象并期望它处理工作。
您是否要添加具有相同唯一 ID 的对象,还是要添加一个,然后更新现有行/对象以将名称属性从“oiu”更改为“ois”。如果是前者,不要将“id”设置为 pkid。如果是后者,请不要告诉 EF 您要添加该对象两次。添加一次,更新现有对象。
So, what are you trying to do? You've told EF and the database (I assume) that "id" is the unique identifier for an object/row. Then, you've told it that you want to add two objects with the same unique id (of "1") and expecting it to handle work.
Do you want to add to objects with the same unique ID, or do you want to add one, then update that existing row/object to change the name property from "oiu" to "ois". If it's the former, don't make "id" a pkid. if it's the latter, don't tell EF that you want to add the object twice. Add it once, the update the existing object.
您只能将对象连接到上下文一次(通过从数据库加载对象或调用
Attach
或AddObject
)。将对象连接到上下文后,您有责任对所有修改使用相同的实例。上下文使用身份映射模式 - 这意味着它通过对象的唯一标识(基于主键和实体集的实体键)来跟踪对象,并且仅允许具有给定实体键的类型的一个实例。唯一的例外是添加新对象,其中EntityKey
在保存更改之前是临时的,但如果将状态更改为Modified
,则情况并非如此。如果您不知道其余测试中的实例,您可以查询
ObjectStateManager.GetObjectStateEntries
并搜索您的实例(每个条目都有引用该实例的Entity
属性)。You can connect object to the context only once (by either loading the object from the database or calling
Attach
orAddObject
). Once you connect the object to the context it is your responsibility to use the same instance for all modification. The context uses identity map pattern - it means that it tracks objects by their unique identification (Entity key based on primary key and entity set) and allow only one instance of the type with given entity key. The only exception is adding new objects whereEntityKey
is temporary until saving changes but it is not the case if you change state toModified
.If you don't know the instance in the rest of your test you can query
ObjectStateManager.GetObjectStateEntries
and search for your instance (each entry hasEntity
property referencing the instance).