序文
これはおそらくすでにクレイジーな質問と見なされていることを知っていますが、すべてのデータ (つまり、すべてのエンティティと関係) を から別のストアにバックアップされた新しく作成された にコピーする方法について、最も教育を受けたアドバイスと実証済みの推奨事項を探しています。 . Entity Framework での EntityConnections と ObjectContexts の「複製」を参照して、これをどのように設定しているかを確認してください。ObjectContext
ObjectContext
はじめに
Cloning data on Entity Frameworkを見てきましたが、
enchilada 全体、つまりオブジェクト グラフ全体 (すべてのエンティティと関係)を探しています。後で、オブジェクト グラフのどの部分をより細かく選択するかについて説明します)
以下の私の更新によると、私はシリアル化を機能させていませんが、特別な場合にのみ使用しています。それほど複雑な作業ではないように感じますが、驚くほどやりがいがあります。それを機能させる方法についての洞察が絶対に必要です。
ステップ1
OK、これは私がこれまでに試したことです。
Detach
/パワー デュオを使用するとAttach
、リレーションシップが無効になることは承知しています。<strong>実際には、オブジェクト グラフ全体を保持したいと考えています。
したがって、ルートエンティティをMergeOption.NoTracking
次のオプションでロードすることを考えていました。
var serializer = new DataContractSerializer(typeof(Root));
var query = (ObjectQuery<Root>) sourceContext.Roots
.Include(d => d.Children.Select(c => c.MoreChildren.Select(r => r.EvenMoreChildren)))
.Include(d => d.Children.Select(c => c.MoreChildren.Select(r => r.MoreAndMoreChildren)))
.Include(d => d.Children.Select(c => c.MoreChildren.Select(r => r.Shizzle)));
foreach (var d in query.Execute(MergeOption.NoTracking)) {
//sourceContext.Detach(d); // not needed
Print(d);
using (var ios = new MemoryStream()) {
serializer.WriteObject(ios, d);
ios.Seek(0, SeekOrigin.Begin);
var dd = (Root) serializer.ReadObject(ios);
//Console.WriteLine(string.Join(",", dd.EntityKey.EntityKeyValues.Select(k => k.Key + "=" + k.Value)));
targetContext.Roots.AddObject(dd);
}
}
エンティティを非追跡としてロードしているため、sourceContext.Detach(d)
もう呼び出す必要はありません。
メソッドはPrint
単に子オブジェクト ツリーを出力し、その時点まではうまくいっていることを示します (巨大で無関係なので、ここでは示しません)。
serializer.WriteObject(ios, d)
しかし、今ではすべてが次のメッセージで@ を吹き飛ばしています:
「マージ オプションでオブジェクトが返される場合、ロードは、またはにオブジェクトが含まれていないNoTracking
場合にのみ呼び出すことができます。」EntityCollection
EntityReference
(シリアライザーはおそらく関連するエンティティを遅延ロードしようとしているため、これは理にかなっています。)
を使用しない場合はNoTracking
、エンティティをデタッチする必要がありますが、関係が失われることを覚えておいてください...
ステップ2
もちろんsourceContext.ContextOptions.LazyLoadingEnabled = false
、シリアル化ループを実行する直前に設定を試みましたが、上記のエラーは修正されましたが、悪名高い結果になります:
「このオブジェクトの と一致しないプロパティ値EntityReference
があるため、オブジェクトを追加または添付できませんでした。」EntityKey
EntityKey
sourceContext.Detach(d)
また、ルートをロードしたため、まだコメントを解除できないことを覚えておいてくださいNoTracking
...
ステップ 3
シリアライゼーションの前に設定しようとしましEntityKey = null
たが、複製されたエンティティのデシリアライゼーションの後でも...すべて役に立たなかった:
sourceContext.ContextOptions.LazyLoadingEnabled = false;
foreach (var d in query.Execute(MergeOption.NoTracking)) {
//sourceContext.Detach(d);
Print(d);
d.EntityKey = null;
using (var ios = new MemoryStream()) {
serializer.WriteObject(ios, d);
ios.Seek(0, SeekOrigin.Begin);
var dd = (Root) serializer.ReadObject(ios);
if (dd.EntityKey != null) {
Console.WriteLine("Deserialized EntityKey: {0}", string.Join(",", dd.EntityKey.EntityKeyValues.Select(k => k.Key + "=" + k.Value)));
dd.EntityKey = null;
}
targetContext.Roots.AddObject(dd);
}
}
怪しいのは、上記の例外である血まみれの「オブジェクト」が何であるかさえ知らないということです。
私は本当に、本当に、本当に、この問題を解決するために純粋にEFのアプローチをしようとしているのですか?
私は完全に運命づけられていますか?!?!?! :(