Entity Framework 4.0 has no in-built way to create a copy or clone an
EntityObject. This simple method does just that - taking an
EntityObject and returning a new one with the properties copied from the one supplied.
Two other methods have been popularized to clone an
- Serializing the object, then deseralizing it to create an exact replica deep copy, and
- Using the
ObjectContext.Detach() method, then using the detached object as a clone.
Unfortunately, there are often problems associated when developing a front end GUI, such as a Windows Forms or WPF application with these methods, such as: the cloned copy has the same
EntityKey, references to related data are lost and your UI interface loses the detached object even though the data store has not!
This third way uses reflection to copy the necessary properties to a new object of the same type.
Using the Code
Simply call the method supplying your
EntityObject and optionally whether you want the key Properties to be copied as well (typically when calling the method for an
EntityObject, you do not want the key(s) copied, otherwise there will be a duplicate key exception when adding, however you probably will want the keys copied if you are calling the method on related data - see the example below).
public static T CopyEntity<T>(MyContext ctx, T entity,
bool copyKeys = false) where T : EntityObject
T clone = ctx.CreateObject<T>();
PropertyInfo pis = entity.GetType().GetProperties();
foreach (PropertyInfo pi in pis)
EdmScalarPropertyAttribute attrs = (EdmScalarPropertyAttribute)
foreach (EdmScalarPropertyAttribute attr in attrs)
if (!copyKeys && attr.EntityKeyProperty)
pi.SetValue(clone, pi.GetValue(entity, null), null);
For example, say you had an entity:
Customer, which had the Navigation Property:
Orders. You could then copy the
Customer and their
Orders using the above method like so:
Customer newCustomer = CopyEntity(myObjectContext, myCustomer, false);
foreach(Order order in myCustomer.Orders)
Order newOrder = CopyEntity(myObjectContext, order, true);
newOrder will initially be related to
newCustomer because we copied the keys from the old order. Not to worry though:
newCustomer.Orders.Add(newOrder) will update
newOrder to reference
EntityObject has an auto-generated key, beware not to
copyKeys = true so you keep the auto-generated key.