C# でのディープ クローン作成に関する多くの情報があるようですが、クローンしようとしているオブジェクトが Entity Framework によってデータベースから引き出されています。私が持っている例は次のとおりです。
public class Parent
{
public int ParentID { get; set; }
public string Name { get; set; }
public virtual Person Owner { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int ChildID { get; set; }
public string Name { get; set; }
}
親エンティティとそれに関連するすべてのオブジェクトのコピーを作成し、この新しいグラフをデータベースに保存したいと考えています。ここで詳しく説明されているように、シリアル化可能なアプローチを使用してみましたが、遅延読み込みのため、子オブジェクトが含まれることはありません (上記の例は簡単です。実際には多くの子が存在するため、すべてを積極的に読み込むことは長期的には維持できません)。
また、次のように、各 POCO に DeepClone メソッドを配置しようとしました。
public Parent DeepClone()
{
Parent clone = (Parent)this.MemberwiseClone();
clone.Owner = this.Owner;
clone.Children = new Collection<Child>();
foreach (Child c in this.Children)
{
Child child = c.DeepClone();
clone.Children.Add(child);
}
return clone;
}
しかし、clone.Children.Add(child) は InvalidOperationException 「プロキシに格納されているエンティティ ラッパーが同じプロキシを参照していません」をスローしています。
誰かがこれに対する正しい解決策を見つけるのを手伝ってくれますか? 要約すると、EF 水和 POCO の完全なオブジェクト グラフを複製し、すべてのオブジェクトを新しいデータとしてデータベースに保存できるようにしたいと考えています。
助けてくれてありがとう。
アップデート
Ladislav Mrnka が提案したように、私は ProxyDataContractResolver を使用して DataContractSerializer ルートをたどり、EF プロキシとうまく連携できるようにしました。ただし、このアプローチは、オブジェクトをデータベースに保存するときに、既に存在するもののコピーを取得するため、問題のあるグラフ内のすべてをシリアル化するようです。たとえば、Parent に ParentType があるとします。新しい ParentType を作成するためではなく、Parent クローンが元の ParentType を参照するようにします。
したがって、ParentType がシリアライゼーションの一部になるのを止める方法が必要です。ParentType プロパティを [IgnoreDataMember] としてマークすることはできますが、この方法ではプロパティが失われる可能性があります。DataContractSerializer を構成して、指定した型のみをシリアル化する方法はありますか?