3
votes

I have the following LINQ to SQL objects (for example)

class Parent{
    int id; // primary key
    IEnumerable<Child> children;
}

class Child{
    int id; // primary key 
    string field1;
    int field2;
}

I need to deep clone a Parent and save it to the database but with COPIES of the children i.e. NOT referencing the existing children.

I have used this method to do the clone, but am looking for an elegant way of iterating through the parent and children properties (given that there could be a large number of child objects, cascading much further than 1 level deep) and setting their primary keys to 0 so that when I submit the cloned object to the database, LINQ to SQL takes care of creating the new children.

1

1 Answers

2
votes

You may try the following extension method which uses System.Reflection:

public static T DeepCopy<T>(this T parent) where T : new()
{
    var newParent = new T();
    foreach (FieldInfo p in typeof(T).GetFields())
    {
        if (p.Name.ToLower() != "id")
            p.SetValue(newParent, p.GetValue(parent));
        else
            p.SetValue(newParent, 0);
        if (p.FieldType.IsGenericType &&
            p.FieldType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            dynamic children = p.GetValue(parent);
            dynamic newChildren = p.GetValue(parent);
            for (int i = 0; i < children.Length; i++)
            {
                var newChild = DeepCopy(children[i]);
                newChildren.SetValue(newChild, i);
            }
        }
    }
    return newParent;
}