Cloning Data for Entity Framework

I am creating software where a user can create a new product based on an older product.

Now I need to do copy / clone operations with the Entity Framework. First, I started writing like this:

 foreach (sourcedata1 in table1)
 {
    ... create new table
    ... copy data
    ... create guid
    ... add
    foreach (sourcedata2 in table2)
    {
        ... create new table
        ... copy data
        ... create guid
        ... add       

        ... and so on
    }
 }

The problem is that this is not a very good way to do this. Is there any information about the cloned view (except for Guid, which should be generated for new lines) or do I need to manually copy everything?

Another solution

You can also use EmitMapper or AutoMapper to copy properties.

+48
entity-framework
Feb 02 2018-10-02T00
source share
6 answers
+15
Feb 10 '10 at 19:14
source share
β€” -

To clone Entity in the Entity Framework, you could simply detach the object from the DataContext and then add it to the EntityCollection .

 context.Detach(entity); entityCollection.Add(entity); 



Update for EF6 + (from comments)

 context.Entry(entity).State = EntityState.Detached; entity.id = 0; entity.property = value; context.Entry(entity).State = EntityState.Added; context.SaveChanges(); 
+61
Jun 30 '10 at 19:34
source share
 public static EntityObject Clone(this EntityObject Entity) { var Type = Entity.GetType(); var Clone = Activator.CreateInstance(Type); foreach (var Property in Type.GetProperties(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.SetProperty)) { if (Property.PropertyType.IsGenericType && Property.PropertyType.GetGenericTypeDefinition() == typeof(EntityReference<>)) continue; if (Property.PropertyType.IsGenericType && Property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>)) continue; if (Property.PropertyType.IsSubclassOf(typeof(EntityObject))) continue; if (Property.CanWrite) { Property.SetValue(Clone, Property.GetValue(Entity, null), null); } } return (EntityObject)Clone; } 

This is a simple method that I wrote. It should work for most people.

+9
Apr 6 2018-11-11T00:
source share

To add a new row whose contents are based on an existing row, follow these steps:

  • Get an object based on the start line.
  • Set the state of the record to add the object.
  • Change entity.
  • Save changes.

Here is an example:

 var rabbit = db.Rabbits.First(r => r.Name == "Hopper"); db.Entry(rabbit).State = EntityState.Added; rabbit.IsFlop = false; db.SaveChanges(); 
+8
Jul 09 '14 at 18:42
source share

If you want to create a copy of the object for comparison later in your code execution, you can select the object in the new db context.

If, for example, you update an object, then later in the code you want to compare the updated and original object:

 var db = new dbEntityContext(); var dbOrig = new dbEntityContext(); var myEntity = db.tblData.FirstOrDefault(t => t.Id == 123); var myEntityOrig = dbOrig.tblData.FirstOrDefault(t => t.Id == 123); //Update the entity with changes myEntity.FirstName = "Gary"; //Save Changes db.SaveChnages(); 

At this point, myEntity.FirstName will contain "Gary" , while myEntityOrig.FirstName will contain the original value. It is useful if you have a function for registering changes, where you can go to the updated and original object.

0
Apr 13 '15 at 16:30
source share

A very short way to duplicate objects using generics (VB, sorry).
It copies foreign key values ​​(external identifiers), but does not load related objects.

 <Extension> _ Public Function DuplicateEntity(Of T As {New, Class})(ctx As myContext, ent As T) As T Dim other As New T 'T is a proxy type, but New T creates a non proxy instance ctx.Entry(other).State = EntityState.Added 'attaches it to ctx ctx.Entry(other).CurrentValues.SetValues(ent) 'copies primitive properties Return other End Function 

For example:

 newDad = ctx.DuplicateEntity(oDad) newDad.RIDGrandpa ' int value copied newDad.Grandpa ' object for RIDGrandpa above, equals Nothing(null) newDad.Children ' nothing, empty 

I don’t know exactly how to restart Grandpa in this case.
This does not work:

 ctx.SaveChanges() ctx.Entry(newDad).Reload() 

but really, no problem. I would prefer to assign Grandpa manually if I need it.

 newDad.Grandpa = oDad.Grandpa 

EDIT: As MattW suggests in your commentary , separating and discovering a new object, you load its children (not collections).

 ctx.Entry(newDad).State = EntityState.Detached ctx.Find(newDad.RowId) 'you have to know the key name 
0
Jan 25 '16 at 21:47
source share



All Articles