Click here to Skip to main content
13,297,799 members (47,468 online)
Click here to Skip to main content
Add your own
alternative version


33 bookmarked
Posted 19 Dec 2010

Cloning the Entity object and all related children using the Entity Framework

, 8 May 2012
Rate this:
Please Sign up or sign in to vote.
Cloning the Entity object and all its children using the Entity Framework, using LINQ and Reflection.


There are a lot of real world scenarios where the requirement is to copy huge records and all the related records using simple interfaces, which can be reused with very little changes rather than creating all over again. Here in this article, we will see a simple way to crack this problem in the LINQ to Entities world. This article tries to solve the following problems:

  • Entity lazy loading: Loads the entity and all its associations in one method call.
  • Entity cloning: How to clone an Entity and all its associations in LINQ to Entities (Entity Framework). This involves popping the data into the database back after cloning.

Note:new version fixed error 'An Object w with Same Key  is already exists '


This article uses the following techniques:

  • Serialization - For cloning an Entity.
  • Reflection - For dynamically invoking methods and accessing attributes. Reflection is used to implement loading the child objects and clearing the entity reference from the cloned object.
  • LINQ - LINQ is used across the implementation.
  • Extension Methods - The Entity object is extended to implement the described functionalities.

This article will focus more on the solution and logic rather than explaining the basics of these techniques.

Using the code

The sample project is a simple Employee master creation application with some CRUD operations. This was implemented with ASP.NET MVC and the Entity Framework.

ER diagram

Folder and file details in the attached project

  • DbScript/efcloningsample.sql - DB scripts for creating the DB objects.
  • CLonehelper.cs - This class has Extension Methods for loading the Entity, cloning the Entity, and clearing the Entity reference.
  • View/ Employeemaster - All the views have content for the Model defined in the database.
  • HomeController - Controller for CRUD operations for Employee.
  • Models/ EmpModel.edmx - EF model created from the database.

Implementation details on CloneHelper.CS

The CloneHelper class has all the logic and implementation. Now we will look at its methods and its role in the implemenatation.


This is an Extension Method to EntityObject. This uses a DataContractSerializer to serialize the object. The cloned Entity will be returned back to the caller.

public static T Clone<t>(this T source) where T:EntityObject  { 
    var obj = new System.Runtime.Serialization.DataContractSerializer(typeof(T)); 
    using (var stream = new System.IO.MemoryStream())
        obj.WriteObject(stream, source);
        stream.Seek(0, System.IO.SeekOrigin.Begin);
        return (T)obj.ReadObject(stream); 

LoadAllChild will load all the associated child objects of the base Entity from the database. The LINQ query will get the child objects, and using Reflection, the Load method is invoked on all the child objects. There is a check on objects to make sure they are loaded twice. This is implemented using a lazy loading logic.

public static EntityObject LoadAllChild(this EntityObject source)
    List<propertyinfo> PropList = (from a in source.GetType().GetProperties()
                                   where a.PropertyType.Name == "EntityCollection`1"
                                   select a).ToList();
    foreach (PropertyInfo prop in PropList)
        object instance = prop.GetValue(source, null);
        bool isLoad = 
          (bool)instance.GetType().GetProperty("IsLoaded").GetValue(instance, null);
        if (!isLoad)
            MethodInfo mi = (from a in instance.GetType().GetMethods()
                             where a.Name == "Load" && a.GetParameters().Length == 0
                             select a).FirstOrDefault();

            mi.Invoke(instance, null);
    return (EntityObject)source;

This method is used to clear the Entity Reference on the cloned Entity. The cloned Entity will be attached to the object only after the Entity References are cleared. The cloned object should be treated as new data and should create new Primary Keys and associate with Referential Integrity. Once the Entity Reference is cleared on the cloned object, the Framework will create temporary keys for associations (will treat this as a new Entity and follow the same logic). When data is moved to the database, the original keys are created and associated back to the EF model.

This method is again an extension of EntityObject. The bcheckHierarchy attribute is used to decide the logic needed to be applied only with the base object or required for all the child objects. Basically, there are two attributes: EntityKey and EntityReferences. EntityKey is set to null during this process. There is also a recursive call initiated to clear the Entity in the child objects.

public static EntityObject ClearEntityReference(this EntityObject source, 
                                                bool bcheckHierarchy)
    return source.ClearEntityObject(bcheckHierarchy);

private static T ClearEntityObject<t>(this  T source, 
                 bool bcheckHierarchy) where T : class
    //Throw if passed object has nothing
    if (source == null) { throw new Exception("Null Object cannot be cloned"); }
    // get the TYpe of passed object 
    Type tObj = source.GetType();
    // check object Passed does not have entity key Attribute 
    if (tObj.GetProperty("EntityKey") != null)
        tObj.GetProperty("EntityKey").SetValue(source, null, null);

    //bcheckHierarchy this flag is used to check
    //and clear child object releation keys 
    if (!bcheckHierarchy)
        return (T)source;

    // Clearing the Entity for Child Objects 
    // Using the Linq get only Child Reference objects   from source object 
    List<propertyinfo> PropList = (from a in source.GetType().GetProperties()
               where a.PropertyType.Name.ToUpper() == "ENTITYCOLLECTION`1"
               select a).ToList();

    // Loop thorough List of Child Object and Clear the Entity Reference 
    foreach (PropertyInfo prop in PropList)
        IEnumerable keys = 
          (IEnumerable)tObj.GetProperty(prop.Name).GetValue(source, null);
        foreach (object key in keys)
            //Clearing Entity Reference from Parnet Object
            var ochildprop = (from a in key.GetType().GetProperties()
                              where a.PropertyType.Name == "EntityReference`1"
                              select a).SingleOrDefault();

            ochildprop.GetValue(key, null).ClearEntityObject(false);

            //Clearing the the Entity Reference from
            //Child object .This will recrusive action
    return (T)source;

Sample implementation

The sample application attached has an Employee master table with two child tables and a grandchild table.

  • Employee (Level 1)
  • EmpAddress (Level 2)
  • EmpBasesal (Level 2)
  • EmpSalDetail (Level 3)

When the user wants to clone on employee data, he selects an employee and clones it. There are two options provided for the user: clone only the parent /base Entity, or clone parent, child, and grand-child.

The implementation does not have any restrictions to any depth/breath of the association level. It will support any level.

The sample has three level hierarchies:

public ActionResult Clone(int id)
    //Load the Empbasic into Context
    var Emp = (from a in osamp.Employees
               where a.EMPID == id
               select a).FirstOrDefault();
    //Load EmpAddress using lazy load
    //  Emp.EmpAddresses.Load();
    //Call the extesnion Method Clone(cast is requried
    //as it was a Entity Object)
    var EMpnew =  Emp.Clone();

    //Clear Entity Values of New Object 
    EMpnew.ClearEntityReference(false );
    //detach the Load empbasic from Context
    //Add new Clone Object and save it DB 
    osamp.AddToEmployees((Employee)EMpnew );
    return RedirectToAction("index"); ;

public ActionResult CloneChild(int id)
    var Emp = (from a in osamp.Employees
                where a.EMPID == id
                select a).FirstOrDefault();
                //Load EmpAddress using lazy load

    //Call the extesnion Method Clone(cast is requried
    //as it was a Entity Object)
    var Empnew =Emp.Clone();
    //Detach the real Object 
    //Clear the Entities in the Cloned object

    //Attach and save the clone in database

    return RedirectToAction("index");

System requirements

The code and sample will work on .NET Framework 4.0.


The following blogs helped to a great extent:


I wrote a blog on the same implementations with ADO.NET 3.5, but will work only to two levels of association and some methods have become obsolete. This code will have a few issues on .NET 3.5. This solution can be implemented by just including the CloneHelper class into a project. Hope this will help a few real time scenarios and increase developer productivity. Happy coding!


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer (Senior)
India India
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionClone Method Hangs.... Pin
songstre0120-Nov-13 5:52
membersongstre0120-Nov-13 5:52 
AnswerRe: Clone Method Hangs.... Pin
eaaeaa24-Dec-13 3:25
membereaaeaa24-Dec-13 3:25 
QuestionDo you have a similar solution for Entity Framework 5 ? Pin
parvez_pathan12-Feb-13 4:12
memberparvez_pathan12-Feb-13 4:12 
GeneralDownload Link Doesn't Work Pin
wsamoht19-Jun-12 5:00
memberwsamoht19-Jun-12 5:00 
QuestionHave you looked into doing something similar with Code First? Pin
xiard17-Jun-12 6:44
memberxiard17-Jun-12 6:44 
QuestionGetting the following error when I attempt to clone an employee 'An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.' Pin
scallejo14-Feb-12 13:01
memberscallejo14-Feb-12 13:01 
AnswerRe: Getting the following error when I attempt to clone an employee 'An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.' Pin
Appusamy.subbian8-May-12 2:34
memberAppusamy.subbian8-May-12 2:34 
GeneralMy vote of 5 Pin
Member 100567811-Nov-11 20:25
memberMember 100567811-Nov-11 20:25 
GeneralIt fails when object has a parent Pin
Luiz Thomaz16-May-11 9:03
memberLuiz Thomaz16-May-11 9:03 
GeneralRe: It fails when object has a parent Pin
pmasson15-Dec-11 3:18
memberpmasson15-Dec-11 3:18 
I have the same problem. But I tested it on a simple entity with only one child, no parent entity. Anf when I add the cloned entity, I get the "object already exist" error. Can you help me?

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 8 May 2012
Article Copyright 2010 by Appusamy.subbian
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid