如何深度克隆实体并避免导航属性引起的错误?
我的实体上的导航属性导致我的深层克隆失败并出现以下错误:
“ObjectStateManager 中已存在具有相同键的对象”
背景:
用户希望能够克隆父记录及其所有关联的子记录。我可以使用这种简单的技术单独克隆父实体(没有错误):
_context.Detach(currentParentEntity);
_context.AddToParentEntities(currentParentEntity);
_context.SaveChanges();
我发现了该解决方案和另一种有效的浅克隆技术(来自diamandiev)此处。
因为我真正需要的是深层复制,所以我尝试实现所示的序列化克隆技术 此处,此处 和 此处。我的调用代码如下所示:
ParentEntity clonedParentEntity = (ParentEntity)DeepClone(currentParentEntity);
_context.Detach(currentParentEntity);
clonedParentEntity.EntityKey = null;
_context.AddToParentEntities(clonedParentEntity);
_context.SaveChanges();
此代码仅在克隆没有子实体(在导航属性中引用)的 currentParentEntity 时有效。如果子实体存在,我会收到“具有相同键的对象已存在”错误。为什么? 如何深度克隆父实体及其关联的子实体,然后保存克隆记录而不出现任何错误?
提前致谢。
编辑:对于完整接受的答案,请阅读 Ladislav Mrnka 的答案加上评论。
The navigation properties on my entity are causing my deep clone to fail with the error:
"An object with the same key already exists in the ObjectStateManager"
Background:
Users want to be able to clone a parent record and all its associated child records. I'm able to clone the parent entity alone (with no errors) using this simple technique:
_context.Detach(currentParentEntity);
_context.AddToParentEntities(currentParentEntity);
_context.SaveChanges();
I found that solution and another working shallow clone technique (from diamandiev) here.
Since what I really need is a deep copy I've tried implementing the serialization cloning technique shown here, here and here. My calling code looks like this:
ParentEntity clonedParentEntity = (ParentEntity)DeepClone(currentParentEntity);
_context.Detach(currentParentEntity);
clonedParentEntity.EntityKey = null;
_context.AddToParentEntities(clonedParentEntity);
_context.SaveChanges();
This code only works when cloning a currentParentEntity with no child entities (referenced in navigation properties). If child entites exist I get the "object with the same key already exists" error. Why? How can I deep clone both a parent entity and it's associated child entities then save the cloned record without any errors?
Thanks in advance.
EDIT: For the complete accepted answer read Ladislav Mrnka's answer plus the comments.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您确实使用了序列化,则克隆了父实体和子实体 - 这不是您的问题。您的问题是调用
Detach
因为它只会删除您要分离的单个实体(而不是其子实体)。因此,错误是由于添加具有上下文已跟踪的相同键的子项而引起的。If you really used serialization you cloned both parent and child entities - that is not your problem. Your problem is calling
Detach
because it will remove only single entity you are detaching (not its children). So the error is caused by adding children with same keys already tracked by the context.