复制entity framework对象

我有一个EF4.1类X,我想复制它以及它的所有子记录。 XY和XYZ

现在,如果我执行以下操作,则返回错误。

属性“X.ID”是对象的关键信息的一部分,无法修改。

public void CopyX(long ID) { var c = db.Xs.Include("Y").Include("W").Include("YZ").SingleOrDefault(x => x.ID == ID); if (c != null) { c.ID = 0; c.Title = "Copy Of " + c.Title; for (var m = 0; m < c.Ys.Count; m++) { c.Ys[m].ID = 0; c.Ys[m].XID=0-m; for (var p = 0; p < c.Ys[m].Zs.Count; p++) { c.Ys[m].Zs[p].XID = 0 - m; c.Ys[m].Zs[p].ID = 0 - p; } } for (var i = 0; i < c.Ws.Count; i++) { c.Ws[i].ID = 0 - i; c.Ws[i].XID = 0; } db.Entry(c).State = System.Data.EntityState.Added; db.SaveChanges(); } } 

或者是否有其他方式来制作实体对象的副本。

注意:每个W,X,Y,Z都有多个属性。

您需要对整个实体图进行正确的深层复制 – 最好的方法是将原始实体图序列化为内存流并将其反序列化为新实例。 您的实体必须是可序列化的。 它通常与DataContractSerializer一起使用,但您也可以使用二进制序列化。

在entity-framework-5中 ,使用DbExtensions.AsNotracking()非常容易。

返回一个新查询,其中返回的实体不会缓存在DbContext或ObjectContext中。

这似乎是对象图中所有对象的情况。

您只需要真正了解您的图表以及您不希望插入/复制到数据库中的操作。

让我们假设我们有像这样的对象:

 public class Person { public int ID { get; set; } public string Name { get; set; } public virtual ICollection
Addresses { get; set; } } public class Address { public int ID { get; set; } public AddressLine { get; set; } public int StateID { get; set; } public ICollection { get; set; } }

所以为了复制一个人,我需要复制地址,但我不想复制状态。

 var person = this._context.Persons .Include(i => i.Addresses) .AsNoTracking() .First(); // if this is a Guid, just do Guid.NewGuid(); // setting IDs to zero(0) assume the database is using an Identity Column person.ID = 0; foreach (var address in person.Addresses) { address.ID = 0; } this._context.Persons.Add(person); this._context.SaveChanges(); 

如果您希望再次重用这些相同的对象以插入第三个副本,则可以再次运行查询(使用AsNoTracking())或分离对象(示例):

 dbContext.Entry(person).State = EntityState.Detached; person.ID = 0; foreach (var address in person.Addresses) { dbContext.Entry(address).State = EntityState.Detached; address.ID = 0; } this._context.Persons.Add(person); this._context.SaveChanges(); 

C不是副本它是记录,你得到的错误是因为你试图更新它的主键,即使你不是它仍然无法工作。 您需要创建一个新的X实体,然后从检索到的实体的属性中复制值,然后插入新实体。

不确定它是否适用于4.1,来自http://www.codeproject.com/Tips/474296/Clone-an-Entity-in-Entity-Framework-4 :

 public static T CopyEntity(MyContext ctx, T entity, bool copyKeys = false) where T : EntityObject { T clone = ctx.CreateObject(); PropertyInfo[] pis = entity.GetType().GetProperties(); foreach (PropertyInfo pi in pis) { EdmScalarPropertyAttribute[] attrs = (EdmScalarPropertyAttribute[])pi.GetCustomAttributes(typeof(EdmScalarPropertyAttribute), false); foreach (EdmScalarPropertyAttribute attr in attrs) { if (!copyKeys && attr.EntityKeyProperty) continue; pi.SetValue(clone, pi.GetValue(entity, null), null); } } return clone; } 

您现在也可以将相关的entites复制到克隆对象; 假设您有一个实体:Customer,它具有导航属性:订单。 然后,您可以使用上述方法复制客户及其订单:

 Customer newCustomer = CopyEntity(myObjectContext, myCustomer, false); foreach(Order order in myCustomer.Orders) { Order newOrder = CopyEntity(myObjectContext, order, true); newCustomer.Orders.Add(newOrder); } 

我使用Newtonsoft.Json,这个很棒的function。

  private static T CloneJson(T source) { return ReferenceEquals(source, null) ? default(T) : JsonConvert.DeserializeObject(JsonConvert.SerializeObject(source)); }