Search code examples
.netentity-frameworkclonedeep-copy

How can I deep clone an entity and avoid errors caused by navigation properties?


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.


Solution

  • 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.