Seems to be lots of info about deep cloning in C# but the object I am trying to clone is being pulled out of a database by Entity Framework. The example I have is as follows:
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; }
}
I want to make a copy of the Parent entity and all of its related objects and then save this new graph to the database. I have tried using a Serializable approach as detailed here but because of lazy loading, the child objects never get included (my example above is trivial; there are actually lots of children so to eager load all would be un-maintainable long term).
I have also tried to put a DeepClone method on each of my POCOs like so:
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;
}
but clone.Children.Add(child) is throwing up an InvalidOperationException "The entity wrapper stored in the proxy does not reference the same proxy."
Can someone help me find the right solution to this. To summarize I want to be able to clone the full object graph of an EF hydrated POCO and then save all objects to the database as new data.
Thanks for any help.
UPDATE
As suggested by Ladislav Mrnka, I have gone down the DataContractSerializer route, using a ProxyDataContractResolver so that it works nicely with EF proxies. However this approach seems to serialize everything in the graph which is problematic as when saving the object back to the database I get copies of things that already exist. For example, say Parent has a ParentType: I want my Parent clone to reference the original ParentType, not for a new ParentType to be created.
So what I need is a way to stop ParentType being part of the serialization. I can mark the ParentType property as [IgnoreDataMember] but this approach could lead to properties being missed. Is there a way to configure DataContractSerializer so it only serializes the types I tell it to?