使用Entity Framework在数据库之间复制实体

时间:2011-12-24 02:48:20

标签: c# .net sql-server entity-framework-4

拥有2个具有相同模式的独立数据库,我需要使用Entity Framework 4将实体(记录)从一个数据库复制到另一个数据库。

我正在创建2个上下文,但是当我向第二个上下文添加一个实体时,我收到以下错误:

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

我知道如果我使用Detach方法可以避免该错误,但在这种情况下相关实体会丢失!

示例代码:

        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();                
        }

我该如何进行此类操作? 或者,如何在不丢失相关实体的情况下分离实体?

3 个答案:

答案 0 :(得分:8)

一旦错误消息有用 - 实体一次只能属于一个上下文。为了做你想要的事情,你需要在第一个上下文中Detatch每个实体,然后再添加到第二个实体。

就像你说的那样,这会杀死相关实体。不幸的是,你必须处理Detach的这个(恼人的)方面。

答案 1 :(得分:6)

为了将来的参考,以下文章帮助了我:

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

答案 2 :(得分:0)

我可以节省时间的好的解决方案: http://lorifpeterson.com/?p=75

禁用EF跟踪

从数据集中检索一个或多个实体时,可以 告诉实体框架不要跟踪您所做的任何更改 制作该对象,然后将该实体作为新实体添加到 数据集。使用.AsNoTracking,上下文一无所知 关于现有实体。

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复制当前值

使用此技术,您可以从现有的设备中获取当前值 实体对象,并将值设置为新创建的实体对象。

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();