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