Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Entity Framework to copy entities between databases

Having 2 separate databases with the same schema, I need to copy entities (records) from one database to another using Entity Framework 4.

I'm creating 2 Contexts, but I'm getting the following error when I add one entity to the second Context:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

I know I can avoid that error if i use the Detach method, but in that case the related entities are lost!

Sample code:

        var cx = new MyEntities();

        //eager load related tables
        var allEntities = from x in cx.Reservation.Include("Detail.MoreDetail")
                  select x;

        // new instance of context but connected to a second database
        var cx2 = new MyEntities( new ConnectionString...);
        foreach (var e in allEntities)
        {
            //cx.Detach(reservation);  // can't detach, or related entities will be lost
            cx2.AddToReservation(reservation);  // error happens here!
            cx2.SaveChanges();                
        }

How can I perform such operation? Alternatively, how can I detach the entity without losing the related entities?

like image 209
pvieira Avatar asked Dec 24 '11 02:12

pvieira


2 Answers

A good solution which can save time: http://lorifpeterson.com/?p=75

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();
like image 61
Amr Elgarhy Avatar answered Oct 16 '22 14:10

Amr Elgarhy


For future reference, the following article helped me:

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

like image 31
pvieira Avatar answered Oct 16 '22 14:10

pvieira