Entity Framework 6 克隆父项和数据库中的所有子项
Entity Framework 6 clone parent and all childrens in database
我正在尝试复制一个对象(Parent)及其关系(Children1、Children2、Children3 和 Children4),为数据库中的每个对象创建一个新 ID,但它仍然失败。有什么方法可以做到这一点吗?
以下是对象的结构及其关系。拜托,我非常需要有人帮助我。
public class Parent
{
[PrimaryKey]
public long IdParent {get; set;}
public string Description {get; set;}
public string OtherValue {get; set;}
public virtual ICollection<Children1> Childrens1 {get; set;}
}
public class Children1
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
public string Description {get; set;}
public virtual Parent Parent {get; set;}
public virtual ICollection<Children1> Childrens1 {get; set;}
}
public class Children2
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren2 {get; set;}
public string Description {get; set;}
public virtual Children1 Children1 {get; set;}
}
public class Children3
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren3 {get; set;}
public string Description {get; set;}
public virtual Children1 Children1 {get; set;}
public virtual ICollection<Children4> Childrens4 {get; set;}
}
public class Children3
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren3 {get; set;}
[PrimaryKey]
public long IdChildren4 {get; set;}
public string Description {get; set;}
public virtual Children3 Children3 {get; set;}
}
在这种情况下最好的办法是从上下文中分离对象然后重新插入它,但这种方法的唯一问题是分离父对象不会分离相关对象,你必须显式分离所有相关对象,然后重新插入它们以制作它们的克隆
context.Detach(object);
context.SaveChanges(object);
context.Entry(object).State = EntityState.Added;
context.SaveChanges();
这就是我的处理方式。从没有跟踪的上下文中检索所有父子,并将它们添加回上下文以进行克隆。
(我只是根据您的实体图展示示例代码,因为您的实体模型 类 与它不匹配。)
public Item DeepClone(Parent item)
{
Parent itemClone = db.Parents
.Include(i => i.Childrens1.Select(c => c.Childrens2 ))
.Include(i => i.Childrens3.Select(c => c.Childrens4 ))
.AsNoTracking()
.FirstOrDefault(i => i.IdParent == item.IdParent);
db.Items.Add(itemClone);
db.SaveChanges();
return itemClone;
}
我正在尝试复制一个对象(Parent)及其关系(Children1、Children2、Children3 和 Children4),为数据库中的每个对象创建一个新 ID,但它仍然失败。有什么方法可以做到这一点吗?
以下是对象的结构及其关系。拜托,我非常需要有人帮助我。
public class Parent
{
[PrimaryKey]
public long IdParent {get; set;}
public string Description {get; set;}
public string OtherValue {get; set;}
public virtual ICollection<Children1> Childrens1 {get; set;}
}
public class Children1
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
public string Description {get; set;}
public virtual Parent Parent {get; set;}
public virtual ICollection<Children1> Childrens1 {get; set;}
}
public class Children2
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren2 {get; set;}
public string Description {get; set;}
public virtual Children1 Children1 {get; set;}
}
public class Children3
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren3 {get; set;}
public string Description {get; set;}
public virtual Children1 Children1 {get; set;}
public virtual ICollection<Children4> Childrens4 {get; set;}
}
public class Children3
{
[PrimaryKey]
public long IdParent {get; set;}
[PrimaryKey]
public long IdChildren1 {get; set;}
[PrimaryKey]
public long IdChildren3 {get; set;}
[PrimaryKey]
public long IdChildren4 {get; set;}
public string Description {get; set;}
public virtual Children3 Children3 {get; set;}
}
在这种情况下最好的办法是从上下文中分离对象然后重新插入它,但这种方法的唯一问题是分离父对象不会分离相关对象,你必须显式分离所有相关对象,然后重新插入它们以制作它们的克隆
context.Detach(object);
context.SaveChanges(object);
context.Entry(object).State = EntityState.Added;
context.SaveChanges();
这就是我的处理方式。从没有跟踪的上下文中检索所有父子,并将它们添加回上下文以进行克隆。
(我只是根据您的实体图展示示例代码,因为您的实体模型 类 与它不匹配。)
public Item DeepClone(Parent item)
{
Parent itemClone = db.Parents
.Include(i => i.Childrens1.Select(c => c.Childrens2 ))
.Include(i => i.Childrens3.Select(c => c.Childrens4 ))
.AsNoTracking()
.FirstOrDefault(i => i.IdParent == item.IdParent);
db.Items.Add(itemClone);
db.SaveChanges();
return itemClone;
}