On a recent project, I had come across the need to copy an existing EF Entity. Upon my research, I found several ways to accomplish this task. One way is to create a new object and manually assign the property values using the existing object values. You can also use some kind of mapping utility if it supports deep copying. However, I will demonstrate two alternative ways to clone an Entity object using EF techniques.
Disable EF Tracking
When you are retrieving an entity or entities from a dataset, you can tell Entity Framework not to track any of the changes that you are making to that object and then add that entity as a new entity to the dataset. With using .AsNoTracking, the context doesn’t know anything about the existing entity.
var entity = context.MyDataSet .AsNoTracking() .FirstOrDefault(e => e.Id == 1); context.MyDataSet.Add(entity); context.SaveChanges();
You can also include child entities as well
var entity = context.MyDataSet .AsNoTracking() .Including(ds => ds.MyChildEntities) .FirstOrDefault(e => e.Id == 1);
context.MyDataSet.Add(entity); context.SaveChanges(); // creates a new object graph in the database
EF Copying Current Values
Using this technique, you can get the current values from an existing entity object and set the values to your newly created entity object.
var originalEntity = context.MyDataSet .FirstOrDefault(e => e.Id == 1); var entity = new MyDataSetEntity(); context.MyDataSet.Add(entity); //Create and add new entity object to context before setting its values var originalEntityValues = Context.Entry(originalEntity).CurrentValues; Context.Entry(entity).CurrentValues.SetValues(originalEntityValues); //Copy values from original entity to new entity entity.MyProperty1 = "Changed value"; // make any changes to the new entity entity.MyProperty2 = "Another changed value"; context.SaveChanges();
Many Thanks that’s work for me ,,
I think best method to cloning Entities in EF is Copy Values
Your welcome! I’m glad it worked for you.
Hi,
any idea about child’s child elements? In other words if a child element has it self a child element how we can copy recursively the whole tree?
Thank you in advance
Pino
You can use Including for child elements. In order to copy the whole tree, you will have to write your own recursive method. Here’s some ideas how: https://stackoverflow.com/questions/33875260/entity-framework-6-deep-copy-clone-of-an-entity-with-dynamic-depth
Many thanks, that´s work for me too.
i spend lot of time looking for something like that.
Disable EF Tracking worked very well in EF6 for me.
But, to make it work, I had to:
+ change the “.Including(..” to “.Include(”
+ using System.Data.Entity;
to satisfy the compiler.
Changing values before SaveChanges() also works.
Thank you so much.
AsNoTracking() That one little function was the key to unlocking hours of frustration. I needed to retain a massive file upload column in the entity, while allowing a replacement upload if, and only if desired. Couldn’t get EF to copy the values without throwing exception…until now. THANKS!
Glad I was able to help!
Many thanks! This is excellent and saved me a lot of time. I’m still fairly new to EF and had a class with two child collections I needed to clone, I can’t believe how easy it was!
You’re welcome!
You are a saviour Lori! Was looking for a fast ef based solution for an entire month.
Thankyou!
You’re welcome!
I recently found a issue in cloning the way described.
With AsNoTracking() approach, EF will create a new proxy as well for the new entity and there is already an existing proxy for original entity. Thus, there are 2 proxies existing now.
Then, as EF copies properties, it will copy every property whether or not marked with NotMappedAttribute. This will lead to copy a reference to the entity wrapper as well (which is present in original entity).
Thus, now there are two proxies with reference to the same wrapper instance.
Now, if you execute statement below:
…..this.context.Entry(originalEntity).CurrentValues.SetValues(entityCloned)…
an error will be thrown as “The entity wrapper stored in the proxy does not reference the same proxy.”
Thus, with above approaches it become a problem.
I figured out that if I can avoid copying reference to the wrapper, this may work.
What do you think on this issue? Any suggestions to figure it out.
Please mail @mentioned id.
Thank you!
I don’t think you have the values set correctly. Try:
this.context.Entry(entityCloned).CurrentValues.SetValues(originalEntity)
Fantastic post. I just got rid of 50 lines of code by using the first approach “Disabling tracking”. Appreciate your effort for sharing the knowledge.
Thanks. This article is what I’am looking for.
The AsNoTracking method did not work for me initially. I was able to get it working by setting the Id for the retrieved entity to 0 prior to Adding back to the db context. When trying to Add the new entity with the Id still specified as the original Id, I was receiving an error on Add.
Hello Lori,
I tried both options to clone existing row/record, but getting below error:
Cannot insert explicit value for identity column in table ‘Contracts’ when IDENTITY_INSERT is set to OFF.
Any suggestion from your side to solve this problem?
P.S: PK is Identity column
You may need to set the Id to 0 if you are getting identity error.
whoah this blog is excellent i like reading
your articles. Stay up the good work! You already know, lots of individuals are looking round for this info, you can help them greatly.
Hi..
I would like to clone an entity. And it has multiple childs. I am getting below error.
“Message”: “The property ‘Id’ on entity type ‘MyParentTable’ is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key first delete the dependent and invoke ‘SaveChanges’ then associate the dependent with the new principal. ”
}
Any help is appreciated