2011-08-03 1 views
3

EFを使用してあるデータベースから別のデータベースにデータをコピーする必要があります。例えば。私は次の表関係を持っています:フォーム - > FormVersions - > FormLayouts ...我々は両方のデータベースで異なるフォームを持っており、それらを1つのDBに集めたいと考えています。基本的に私はフォームオブジェクトを再帰的に1つのDBからロードし、すべての参照を含む別のDBに保存します。また、2番目のデータベースに同じIDのオブジェクトが存在する場合は、オブジェクトと関連オブジェクトのIDを変更する必要があります。EFを使用して2つのデータベース間でレコードをコピー

Form form = null; 
using (var context = new FormEntities()) 
     { 
      form = (from f in context.Forms 
         join fv in context.FormVersions on f.ID equals fv.FormID 
         where f.ID == 56 
         select f).First(); 
     } 

     var context1 = new FormEntities("name=FormEntities1"); 
     context1.AddObject("Forms", form); 
     context1.SaveChanges(); 

私はエラー受けています:今まで私は、次のコードしている

「のEntityKeyプロパティは専用プロパティの現在の値がnullのときに設定することができます」と

実装にお役立てください。

答えて

4

最も簡単な解決策は、フォーム(新しいオブジェクト)のコピーを作成し、その新しいオブジェクトを追加することです。そうしないと、あなたは試すことができます:

  1. コールcontext.Detach(form)
  2. 設定フォームのEntityKey
  3. コールcontext1.AddObject(form)
+0

解決策を試しました。それは正常に動作しますが、Formオブジェクトに対してのみ有効です。フォームを切り離すと、関連するオブジェクトがすべて失われます。したがって、FormがFormVersionsを10個持っている場合、Formは0 FormVersionsを持ちます。私はルートオブジェクトだけでなく、すべての階層をコピーすることを達成したいと思います。 – zosim

+1

はい、まさに何が起きているのか、Formとそのすべてのリレーションの完全なコピーを作成すること以外は解決策がありません(最も簡単な解決策はFormを直列化および非直列化して完全なクローンを得ることですが、Formは直列化可能でなければなりません)。ありがとう。 –

+0

シリアライゼーションは私の解決策です。しかし、生成EFモデルのデフォルトテンプレートには、エンティティコレクションの[XmlIgnoreAttribute()]属性があります。それは、関連オブジェクトがシリアル化されていないことを意味します。どのようにmodifiyngテンプレートなしで関連オブジェクトをシリアル化するオプションがありますか? – zosim

1

あなたはわずか数の記録を行っている場合は、ラディスラフの提案は、おそらく動作しますが、あなたの場合でしょうがnullに多くのデータを移動している場合は、ストアドプロシージャでこの移動を実行することを検討する必要があります。 DBサーバーからフロントエンドにオブジェクトを移動する必要はなく、サーバーに操作全体を戻すことができます。単一のSPコールがそれをすべて実行します。

パフォーマンスは、あなたのケースでは重要ではないかもしれませんが、より良いでしょう。

+0

返信ありがとうございます。この場合、パフォーマンスは重要ではありません。より重要なのは、私がコピーしたい関連テーブルの大きな階層です。たとえば、3つのテーブルしか書いていませんが、Forms-> FormVersions-> FormLayouts-> LayoutRows-> LayoutColumns-> .... nのように20のテーブルがあります。私はストアドプロシージャでそれを行うことができますが、手動ですべての関連するテーブルをトラバースする必要があります。私はEFが私のためにそれを行うことができるかどうかを発見しています。記事のおかげで – zosim

3

私は最初の2番目のE.J.の答えでしょう。 Entity Frameworkを使用しようとしていると仮定した場合、主な問題領域の1つは関係管理です。コードでは、関連するオブジェクトが選択操作の結果に確実に含まれるように、Includeメソッドを使用する必要があります。あなたが持っている結合はこの効果を持たないでしょう。

http://msdn.microsoft.com/en-us/library/bb738708.aspx

また、物体を取り外すと、自動的に関連するオブジェクトをデタッチしないであろう。同じ方法でそれらをデタッチすることができますが、ここでの問題は、各オブジェクトが切り離されると、コンテキスト内の他のオブジェクトとの関係が壊れてしまうことです。

リレーションシップを手動で復元することもできますが、EntityGraphを調べる価値があります。このフレームワークを使用すると、オブジェクトグラフを定義してから、デタッチなどの操作を実行できます。グラフ全体は、1つの操作で切り離され、その関係はそのまま維持されます。

私のこのフレームワークの経験は、RIA ServicesとSilverlightに関連していますが、これらの操作は.Netでもサポートされていると思います。

http://riaservicescontrib.codeplex.com/wikipage?title=EntityGraphs

EDIT1:私はちょうどEntityGraphのドキュメントをチェックしDetachEntityGraphが、残念ながらあなたのためのオプションとして、それを除外RIA特定の層であることがわかります。

Edit2:次の質問に対するAlex Jameの答えは、問題の解決策です。最初にオブジェクトをコンテキストにロードしないでください - notrackingオプションを使用してください。そうすれば、問題の原因となっているものを切り離す必要はありません。

Entity Framework - Detach and keep related object graph

+0

。私はLadislavのソリューションを使って問題を解決しました。 – zosim

関連する問題