实际上我在解决如何处理添加/更新复杂实体时存在很大问题,而子项可以包含重复项(使用唯一键)。
我尝试将问题分解为核心:
三个实体: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 /或者自己创建关系。
感谢您的时间和帮助!
答案 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