2

似乎有很多关于 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 所以它只序列化我告诉它的类型?

4

0 回答 0