C# 实体框架6如何决定是否应使用ON DELETE级联定义FK
我有一大堆相互关联的课程 让我们以以下类层次结构为例:C# 实体框架6如何决定是否应使用ON DELETE级联定义FK,c#,sql,.net,database,entity-framework-6,C#,Sql,.net,Database,Entity Framework 6,我有一大堆相互关联的课程 让我们以以下类层次结构为例: Class A { // PK public string A_Id // Navigation Property public virtual ICollection<B> MyB{ get; set; } } Class B { // PK public int B_Id // FK - On Delete - NO ACTION <-------
Class A
{
// PK
public string A_Id
// Navigation Property
public virtual ICollection<B> MyB{ get; set; }
}
Class B
{
// PK
public int B_Id
// FK - On Delete - NO ACTION <---------- Difference here
public string A_Id { get; set; }
// Navigation Properties
public virtual A MyA { get; set; }
public List<C> MyC{ get; set; }
}
Class C
{
// PK
public int C_Id
// FK - On Delete - CASCADE <---------- Difference here
public int B_Id { get; set; }
// Navigation Properties
public virtual B MyB { get; set; }
}
A类
{
//主键
公共字符串A\u Id
//导航属性
公共虚拟ICollection MyB{get;set;}
}
B类
{
//主键
公共int B_Id
//FK-删除-不采取行动好吧,经过多次努力,这里是正确的答案:
实体框架默认行为为“删除级联”
但它只能在列不可为空时定义“删除级联”。
因此,如果我们回到这个例子,我们可以看到类A有一个字符串PK(nullable),类B有一个intPK(non-nullable),这就解释了区别
如何解决
最好的解决方案是在
FK属性,否则,EF6引擎会将该属性视为
可为空并在删除时定义->无操作
工作示例:
Class A
{
// PK
public string A_Id
// Navigation Property
public virtual ICollection<B> MyB{ get; set; }
}
Class B
{
// PK
public int B_Id
// FK - On Delete - NO ACTION <---------- Difference here
[Required] <------------------------ SOLUTION =] =] =]
public string A_Id { get; set; }
// Navigation Properties
public virtual A MyA { get; set; }
public List<C> MyC{ get; set; }
}
Class C
{
// PK
public int C_Id
// FK - On Delete - CASCADE <---------- Difference here
public int B_Id { get; set; }
// Navigation Properties
public virtual B MyB { get; set; }
}
A类
{
//主键
公共字符串A\u Id
//导航属性
公共虚拟ICollection MyB{get;set;}
}
B类
{
//主键
公共int B_Id
//FK-删除时-无操作在DbContext类中,您可以使用FluentAPI完成此操作,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.HasOptional(a => a.MyB)
.WithOptionalDependent()
.WillCascadeOnDelete(true);
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.has可选(a=>a.MyB)
.WithOptionalDependent()
.WillCascadeOnDelete(真);
}
它还为您提供了处理非必填字段的灵活性。您好,我尝试了FluentAPI(正如我在问题中提到的)。问题是它创建了第二个FK,这是不需要的。您的代码是否创建了新的FK?我使用了:@Yitzchak您所说的“它创建了第二个FK”是什么意思?请帮助我理解,现在我明白了,当您首先使用代码时,您可以通过保持正确的命名约定来设置表关系。如果您想命名正确的与EF期望的不同,您应该使用以下方法之一创建关系:1.使用注释(如ForeignKey注释)2.使用Fluent Api。在我的例子中,我使用注释定义了我的键,因此当我添加Fluent Api代码时,我得到的FKs比需要的多。(从B类到A类的ID,我有两个FKs)没错,导航属性基本上会在幕后为您创建一个外键。+1对于正确答案,您的答案确实会出现在其他SO帖子中,我的帖子的目的是了解EF的幕后情况,以便开发人员可以为他选择最佳解决方案。