How to make a deep duplicate of an object

.net-4.0 c# entity-framework

Question

I found this snippet here:

public static T DeepClone<T>(this T obj)
    {
        using (var ms = new MemoryStream()) {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ms.Position = 0;
            return (T)bf.Deserialize(ms);
        }
    }

Which says that we can do deep copy of all related objects through this thing.

I'm trying to do a copy like this:

db.Detach(myEntity); 
myEntity.EntityKEy = null;
Entity newEntity = new Entity();
newEntity = DeepClone<Entity>(Entity);
db.Entities.AddObject(newEntity);
db.SaveChanges();

IT works, but still does not copy any nested\related records. what do I do wrong here?

I have this structure Entity->ChildEntity ->ChildChildEntity
-> - one-to-many
so I assume when I copy entity it will also copy all child records.

UPDATE: After suggestions, I did this:

Entity newEntity = new Entity();
Eneity Entity = db.Include("ChildEntity").Where(p=>p.Id==Id).Single();
newEntity = DeepClone<Entity>(Entity);
db.Detach(myEntity); 
myEntity.EntityKEy = null;
db.Entities.AddObject(newEntity);
db.SaveChanges();

Getting exception on AddObject line:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

1
11
5/23/2017 12:03:32 PM

Accepted Answer

The important point is that you must load related entities and create deep clone prior to detaching. If you detach the entity all relations are silently removed because Detach method works only for single entity and entity graph cannot consists of both attached and detached entities. That is a reason why you need serialization instead of simply calling Detach.

Don't forget to turn off lazy loading otherwise your serialization will pull data for other navigation properties from database as well. Also remember that this deep copy will create new version of all entities in the graph so adding the root entity will add all related entities as well.

7
1/26/2012 9:00:53 AM

Popular Answer

The EntityKeys for all the child objects get cloned too, so you need to set each child's EntityKey to null before trying to add them with AddObject.

Entity oldEntity = db.Include("ChildEntity").Where(p => p.Id == Id).Single();
Entity newEntity = oldEntity.DeepClone(); // assuming you've put your DeepClone extension method in a static class so that it can be used as an extension
newEntity.EntityKey = null;
foreach(var childEntity in newEntity.ChildEntities)
{
    childEntity.EntityKey = null;
}
db.Entities.AddObject(newEntity);
db.SaveChanges();


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow