我有一个简单的1:许多聚合关系,让我们说:
public class Parent
{
public string Name {get; set;}
public Child SelectedChild {get; set;}
public Child PublishedChild {get; set;}
public virtual ICollection<Child> AllChildren {get; set;}
}
public class Child
{
public string Name {get; set;}
[Required]
public Parent Father {get; set;}
}
从此模型创建架构时,我收到错误:
在表'Parent'上引入FOREIGN KEY约束'Parent_SelectedChild'可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束
所以我将以下内容添加到OnModelCreating:
modelBuilder.Entity<Child>()
.HasRequired(v => v.Parent)
.WithOptional(c => c.SelectedChild)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Child>()
.HasRequired(v => v.Parent)
.WithOptional(c => c.PublishedChild)
.WillCascadeOnDelete(false);
这可以解决原始错误但我现在得到:
无法确定'xxx.Parent_SelectedChild'关系的主要结尾。 多个添加的实体可能具有相同的主键。
有人可以帮忙吗? 我本来想做的就是在父亲的1:多聚合关系中引用特定的子记录。我假设EF将在父节点上创建INT子id列,例如SelectedChild_Id&amp; PublishedChild_Id(或类似)。
提前致谢 -macon
编辑:回应@Slauma: 我可以使用:
获得生成的模式 modelBuilder.Entity<Parent>()
.HasOptional(p => p.SelectedChild)
.WithOptionalPrincipal()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Parent>()
.HasOptional(p => p.PublishedChild)
.WithOptionalPrincipal()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Parent>()
.HasMany(p => p.AllChildren)
.WithRequired(c => c.Father)
.WillCascadeOnDelete(false);
但是这会在子记录上生成多个FK,例如Parent_Id,Parent_Id1。我只想要一个从Parent到一个子行的引用,例如Parent_SelectedChildId。我是否必须使用父级的int列手动执行此操作?
答案 0 :(得分:2)
我认为你有三个一对多的关系:
modelBuilder.Entity<Parent>()
.HasOptional(p => p.SelectedChild)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Parent>()
.HasOptional(p => p.PublishedChild)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Parent>()
.HasMany(p => p.AllChildren)
.WithRequired(c => c.Father)
.WillCascadeOnDelete(false);
修改强>
我已经使用完全您在问题中提供的Parent
和Child
类测试了上面的映射 - 唯一的例外是我添加了主键属性两个班级:public int Id { get; set; }
。否则EF会抱怨缺少关键财产。此映射不会引发异常并在数据库中创建以下表:
家长表:
- Id int not nullable (PK)
- Name nvarchar(MAX) nullable
- SelectedChild_Id int nullable (FK)
- PublishedChild_Id int nullable (FK)
儿童表:
- Id int not nullable (PK)
- Name nvarchar(MAX) nullable
- Father_Id int not nullable (FK)
因此,预期有三个外键列。
由于您根据评论得到异常,我猜您测试的代码实际上存在一些重要差异。
BTW:将Parent
类的两个导航属性映射为一对一关系,即使不是不可能,也要困难得多。在EF中,您需要在两个表之间使用共享主键来映射一对一关系,因此不可能将两个不同的实体分配给两个导航属性,因为它们不能都具有与父级相同的密钥。