我有类似下面的典型代码:
public class Parent
{
public int Id { get; set; }
public ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
[Required]
public Parent Parent { get; set; }
}
实体框架创建类似于:
create table Children
(
Id int identity constraint [PK_dbo.Children] primary key,
Parent_Id int
constraint FK_dbo.Children_dbo.Parent_Parent_Id
references Parents,
}
然后我添加级联删除:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Parent>()
.HasMany(x => x.Children)
.WithRequired()
//.HasForeignKey(x => x.Parent) // my wrong try
.WillCascadeOnDelete(true);
}
EF创造了类似的东西:
create table Children
(
Id int identity constraint [PK_dbo.Children] primary key,
Parent_Id int
constraint FK_dbo.Children_dbo.Parent_Parent_Id
references Parents,
Parent_Id1 int
constraint FK_dbo.Children_dbo.Parent_Parent_Id1
references Parents,
...
}
即EF创建重复的FK:Parent_Id
和Parent_Id1
。为什么?
我尝试了不同的变种,但我无法摆脱不必要的重复。
请问,任何人都可以帮忙解决这个问题吗?
更新:
迈克尔,非常感谢您的回复。我读了这篇文章并尝试了不同的变体,但遗憾的是没有成功。 [InverseProperty("Parent")]
属性也没有帮助。
在我看来,Parent.Children
是ApplicationUser.YmSites
。 Child.Parent
是YmSite.User
。
刚才,我甚至尝试以下直接的T-SQL脚本:
ALTER TABLE DB_9B2F.dbo.YmSites DROP CONSTRAINT [FK_dbo.YmSites_dbo.AspNetUsers_User_Id]
ALTER TABLE DB_9B2F.dbo.YmSites
ADD CONSTRAINT [FK_dbo.YmSites_dbo.AspNetUsers_User_Id]
FOREIGN KEY (User_Id) REFERENCES AspNetUsers (Id) ON DELETE CASCADE
但我得到错误:
不支持此属性:ApplicationName。
很奇怪。
问题
DbModelBuilder
再次定义它总之,我认为你有2个关系。所以,你不需要做任何事情,只需删除DbModelBuilder
代码
但是,如果您需要对模型构建器执行某些操作,例如关闭级联删除,或者您只是想在那里进行冗余(谁知道原因)。一种方法是通过使用InverseProperty数据注释明确告诉EF你在Parent
和Child
之间有一个关系(一个)
public class Parent
{
public int Id { get; set; }
[InverseProperty("Parent")]
public ICollection<Child> Children { get; set; }
}
注意:通常,反向属性是声明多个关系,但是在这种情况下它可以工作,因为你知道你只想要那种关系
对于一个完整的答案,我试图在下面找到别人的话。
Cascade Delete in One-to-Many Relationships
注意:如果删除了一个或另一个实体,EF会自动删除多对多关系实体的中间表中的相关记录。
因此,EF默认为所有实体启用级联删除效果。