I tried the following to detach a graph of entity objects, and then attach it to a new context:
// create a context
var ctx = new TestEntities();
var parents = ctx.Parents;
// populate the graph
var newParent = new Parent {Nb = 1, Title = "Parent1"};
parents.AddObject(newParent);
newParent.Children.Add(new Child {Nb = 1, Title = "Child1"});
// put all entity objects in Unchanged state before detaching
ctx.SaveChanges();
// detach all entity objects
foreach (var objectStateEntry in ctx.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached))
ctx.Detach(objectStateEntry.Entity);
// create a new context
ctx = new TestEntities();
// attach graphs to new context
foreach (var p in parents)
ctx.Attach(p);
I have two issues with this approach:
- After detaching all entity objects,
newParent.Childrenbecomes empty - An InvalidOperationException is raised when re-attaching saying that “An entity object cannot be referenced by multiple instances of IEntityChangeTracker”.
Does anyone know how to properly detach a graph from an ObjectContext, and re-attach it to another one?
UPDATE:
Ok good news for me, I figured out how to change the underlying database connection within the same ObjectContext, so I don’t need to detach/attach anymore. If anybody’s interested, here’s how I do it (here I use SQLite and change the database file):
var sc = ((EntityConnection)ctx.Connection).StoreConnection;
sc.ConnectionString = @"Data Source=" + newFile + ";";
I’ll accept Ladislav’s answer as it seems to be correct and answers my question as it was asked.
You must create deep clone of the whole graph and attach it to another context. The deep clone is created through the serialization. The common approach is to use
DataContractSerializer:To make this work your entities must not contain circular references (Parent has navigation property to Child and Child has navigation property to Parent) or you must use
DataContract(IsReference=true)andDataMemberattributes on your entities to inform serializer that it must track references to resolve circular reference issue.