似乎有很多关于 C# 中深度克隆的信息,但我试图克隆的对象正被实体框架从数据库中提取出来。我的例子如下:
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:我希望我的 Parent 克隆引用原始 ParentType,而不是创建新的 ParentType。
所以我需要一种方法来阻止 ParentType 成为序列化的一部分。我可以将 ParentType 属性标记为 [IgnoreDataMember] 但这种方法可能会导致属性丢失。有没有办法配置 DataContractSerializer 所以它只序列化我告诉它的类型?