图表可以从ObjectContext中分离出来并重新附加到另一个上吗?

5 c# entity-framework

我尝试了以下内容来分离实体对象的图形,然后将其附加到新的上下文:

// 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);
Run Code Online (Sandbox Code Playgroud)

这个方法有两个问题:

  1. 分离所有实体对象后,newParent.Children变为空
  2. 重新附加说"实体对象不能被IEntityChangeTracker的多个实例引用"时引发InvalidOperationException.

有谁知道如何从ObjectContext中正确分离图形,并将其重新附加到另一个图形?

更新:

对我来说好消息,我想出了如何在同一个ObjectContext中更改底层数据库连接,所以我不再需要分离/连接.如果有人感兴趣,我就是这样做的(这里我使用SQLite并更改数据库文件):

var sc = ((EntityConnection)ctx.Connection).StoreConnection;
sc.ConnectionString = @"Data Source=" + newFile + ";";
Run Code Online (Sandbox Code Playgroud)

我会接受拉迪斯拉夫的回答,因为它似乎是正确的,并回答了我的问题.

Lad*_*nka 3

您必须创建整个图的深度克隆并将其附加到另一个上下文。深度克隆是通过序列化创建的。常见的方法是使用DataContractSerializer

var serializer = new DataContractSerializer(typeof(Parent));
serializer.WriteObject(stream, attachedEntity);
stream.Seek(0, SeekOrgin.Begin);
detachedEntity = (Parent)serializer.ReadObject(stream);
Run Code Online (Sandbox Code Playgroud)

为了使这项工作有效,您的实体不得包含循环引用(父级具有子级的导航属性,子级具有父级的导航属性),或者您必须在实体上使用DataContract(IsReference=true)DataMember属性来通知序列化器它必须跟踪引用以解决循环引用问题。