2012-07-22 6 views
5

私は、エンティティオブジェクトのグラフを切り離し、その後、新しいコンテキストにアタッチするために、次を試してみました:グラフをObjectContextから切り離して別のオブジェクトに再結合することはできますか?

// 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); 

私は、このアプローチには2つの問題があります。

  1. をすべてのエンティティオブジェクトを取り外した後、 newParent.Childrenが空になる
  2. 「エンティティオブジェクトが複数のインスタンスのIEntityChangeTrackerから参照できない」というエラーが返された場合、InvalidOperationExceptionが発生します。

グラフをObjectContextから適切に切り離して別のものに再接続する方法を知っている人はいますか?

UPDATE:私のために

[OK]を良いニュース、私は同じObjectContextは内基盤となるデータベース接続を変更する方法を考え出したので、私はもう取り付け/取り外しする必要はありません。誰もが興味を持っていた場合は、ここで私は(ここで私はSQLiteのを使用して、データベースファイルを変更する)それを行う方法は次のとおりです。

var sc = ((EntityConnection)ctx.Connection).StoreConnection; 
sc.ConnectionString = @"Data Source=" + newFile + ";"; 

正しいと思えるし、それが頼まれたとして、私の質問に答えるように私は、ラディスラフの答えを受け入れるだろう。

答えて

3

グラフ全体のディープクローンを作成し、別のコンテキストに添付する必要があります。深いクローンは、シリアライズによって作成されます。一般的なアプローチは、使用することですDataContractSerializer

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

が、これは循環参照を含めることはできませんあなたのエンティティを動作させるために(親が子供にナビゲーションプロパティを持ち、子は親にナビゲーションプロパティを持っている)か、上のDataContract(IsReference=true)DataMember属性を使用する必要があります。シリアライザに循環参照問題を解決するための参照を追跡する必要があることをエンティティに通知する必要があります。

+0

グラフ内のオブジェクトを参照するアンドゥ/リドゥスタックがあり、ObjectContextを変更するとスタックをスクラップしたくないため、コピーを実行したくありません。同じグラフを使用し続けながら、コンテキストを変更するために使用できる他の方法、またはその接続オブジェクトのみを知っていますか? –

+1

このような場合は、エンティティを切り離してリレーションを保持する方法が現在存在しないため、両方の操作で同じコンテキストを使用する必要があります。そのため、保持するためにコピーを行う必要があります。 –

+0

はい、私はそれを恐れていましたが、ちょっと、私は基本的な接続文字列を変更できることを知りましたので、まずは分離/接続する必要はありません。 –

関連する問題