克隆实体框架的数据

Tx3*_*Tx3 51 entity-framework

我正在创建软件,用户可以根据旧产品创建新产品.

现在我需要使用Entity Framework进行复制/克隆操作.首先,我开始写这样的:

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
   }
}

问题是,这不是一个很好的方法.是否有任何简单的方法克隆信息(除了需要为新行生成的Guid)或者我应该手动复制所有内容?

其他方案

您还可以使用EmitMapper或AutoMapper来复制属性.

Chr*_*l52 65

要在实体框架中克隆实体,您可以简单地从实体中分离实体DataContext,然后将其重新添加到实体框架中EntityCollection.

context.Detach(entity);
entityCollection.Add(entity);
Run Code Online (Sandbox Code Playgroud)

EF6 + 更新(来自评论)

context.Entry(entity).State = EntityState.Detached;
entity.id = 0;
entity.property = value;
context.Entry(entity).State = EntityState.Added;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)

  • 唯一的问题是,如果您分离实体,则会丢失所有引用. (25认同)
  • 注意:如果你分离一个实体,它就不会分离相关实体,所以如果你做var entity = context.MyEntities.Include("MyRelated").首先(t => t.ID == 1)然后是Detach(实体) ),MyRelated仍然在上下文中,这意味着当你调用SaveChanges()时它们会被无意中删除. (10认同)
  • 在EF5 +中我做了这个`context.Entry(entity).State = EntityState.Detached;` (7认同)
  • 对于那些尝试这种方法.请记住,在调用context.SaveChanges()之前,您不会获得新的Id(键值) (3认同)

Tom*_*asi 10

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;
}
Run Code Online (Sandbox Code Playgroud)

这是我写的一个简单的方法.它适用于大多数人.

  • 这需要一些修复.第一个是我认为你打算在foreach语句中使用continue而不是break作为前三行.根据返回的属性的顺序,这将表现不正确.第二个是你需要删除BindingFlags.DeclaredOnly,因为这会导致它从其他实体对象继承的实体对象失败.例如,在我的情况下,工作人员继承自人,但我刚刚获得克隆员工的属性. (5认同)

Edw*_*rey 8

若要添加内容基于现有行的新行,请按照下列步骤操作:

  1. 获取基于起始行的实体.
  2. 将实体的条目状态设置为"已添加".
  3. 修改实体.
  4. 保存更改.

这是一个例子:

var rabbit = db.Rabbits.First(r => r.Name == "Hopper");
db.Entry(rabbit).State = EntityState.Added;
rabbit.IsFlop = false;
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)