EntityFramework添加重复的子项

时间:2016-02-03 09:43:12

标签: .net entity-framework

实际上我在解决如何处理添加/更新复杂实体时存在很大问题,而子项可以包含重复项(使用唯一键)。

我尝试将问题分解为核心:

三个实体:GrandFather 1 --- *父亲* --- *儿童(1对多,多对多)

  public class GrandFather
    {
        [Key]
        public int ID { get; set; }

        public ICollection<Father> RelatedChildren { get; set; }
    }
    public class Father
    {
        [Key]
        public int ID { get; set; }

        public GrandFather RelatedFather;

        public ICollection<Child> RelatedChildren { get; set; }
    }

    public class Child
    {
        [Key]
        public int ID { get; set; }

        [Index("IX_TEST",0,IsUnique=true)]
        public String UniqueKeyPart1 { get; set; }

        [Index("IX_TEST", 1, IsUnique = true)]
        public String UniqueKeyPart2 { get; set; }

        public ICollection<Father> RelatedFathers { get; set; }
    }

所以,实际上有(例如)10个不同的孩子,父亲1可以和父亲2拥有相同的孩子。一个父亲只能有不同的孩子(在这种情况下最多10个)

包含祖父的图表中的结果,其中包含多个父亲(全部不同),其中包含多个孩子

问题: 当我尝试添加祖父时

context.Grandfather.Add(grandfather);
context.SaveChanges();

会出现一个例外情况,例如“无法添加儿童,因为有重复项...在索引IX_TEST上......”

我希望(当然)EF将祖父+所有父亲+他们的关系和孩子+他们的关系插入他们的父亲

我已经尝试了很多不同的方法(迭代孩子并在插入之前/之后附加/分离例如。)我甚至无法在这里列出它们。

问题:

让这种方法正常工作的最佳做​​法是什么?我快要把这一切扔掉,使用普通的SQL /或者自己创建关系。

感谢您的时间和帮助!

1 个答案:

答案 0 :(得分:0)

您遇到的问题是您正在尝试向数据库添加现有实体,因此您将获得Id异常。

我总是找到处理多对多关系的最佳方法,首先是创建映射实体(将生成映射表)。

我的建议是创建一个FatherChild实体:

public class FatherChild
{
    [Key]
    public int FatherId { get; set; }
    public virtual Father Father {get;set;}
    [Key]
    public int ChildId { get; set; }
    public virtual int Child { get; set; }
}

然后更新您的父子课程:

public class Father
{
    [Key]
    public int ID { get; set; }

    public GrandFather RelatedFather;

    public ICollection<FatherChild> RelatedChildren { get; set; }
}

public class Child
{
    [Key]
    public int ID { get; set; }

    // assuming that you only navigate from one entity you only need this ICollection on Father or Child, not on both
    public ICollection<FatherChild> RelatedFathers { get; set; }
}

每次需要时,您都需要创建一个新的映射:     var父亲;     //从数据库中获取父亲或创建一个新父     //对于孩子来说一样     var fatherChild = new FatherChild {         FatherId = father.Id,         childID的= childID的     };

father.RelatedChildren.Add(fatherChild); //assuming that Father is your main entity and is the one holding the navigation property
// persist father in the db