了解使用 fluent api 禁用级联删除

问题描述

我是 asp.net 的新手,我正在学习一门课程,我们在其中添加了这段 使用以下代码从相关表中禁用级联删除代码

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Attendance>()
        .Hasrequired(a => a.Gig)
        .WithMany()
        .WillCascadeOnDelete(false);
        
    base.OnModelCreating(modelBuilder);
}

我想了解很多部分:

  1. 为什么我们用考勤类型定义实体方法,根据我的理解 应该在创建方法时使用此类型来指定返回值,而不是在调用方法时使用。

  2. Hasrequired 是什么意思,withmany 是什么意思?

解决方法

级联删除

假设有另一种类型的链接指向您的出席情况。因此,在数据库中,其他类型(表)将具有 Attendance 表的外键。

如果您尝试删除数据表中的 Attendance 记录,如果该记录在其他表中使用,则会失败。

级联删除会删除除考勤记录以外的所有相关记录。

如果不启用级联删除,删除将失败,因为其他记录需要该考勤记录。

实体

无论是用代码生成数据库还是数据库已经存在,你的表示表的C#类都不能提供所有信息(例如如果不遵守约定,EF就无法知道哪个字段是主键,哪个字段不可为空(见下一点),或者表名是否与类名匹配)。

使用 modelBuilder.Entity<Attendance>(),您将帮助 EF 构建他的“数据库外观的内部模型”。在这种情况下,您向 EF 提供有关“出勤”类型的其他信息。

所以你可以警告 EF 这个表在另一个模式中或者表名不同......

您可能可以为所有实体/表执行此操作。

IsRequired(未在您的示例中使用,但我同意 IsRequiredHasRequired,所以我在这里解释)

IsRequired 用于可空类型。在数据库中,您可以有一个类型“varchar(x) not null”,而在 C# 中它将是一个“字符串”。但是字符串在 C# 中可以为空,因此 HasRequired 是一个配置,它会告诉您的 ORM“是的,该类型可以为空,但在我的配置中不应该是这种情况”。

因此,当 EF 生成数据库时,类型将为“非空”,或者当您的 EF 在调用数据库之前验证实体时,将完成该检查。

必须

它与 IsRequired 的概念相同,但稍微复杂一些,因为它在涉及多个表时使用。例如合同和客户,一个合同归一个客户所有,但一个客户可以有多个合同。因此,在数据库 Contract 表中将有一个指向 Customer 的外键,并且在 Contract 类中将有一个名为 Customer 的(导航)属性。

public class Contract 
{
    public Customer Customer { get; set; }
}

public class Customer
{       
}

modelBuilder.Entity<Contract>()
    .HasRequired(c => c.Customer)

此配置将指示 Contract 具有指向 Customer 的导航属性,这是必需的,这意味着外键不能为 null。如果您希望它可以为空,则应使用 HasOptional

WithMany 现在您配置了 HasRequired,您拥有了 WithMany。这将表明您可以为一个客户拥有多个合同(合同有一个必需的客户,他拥有许多合同:这是一种“一对多”关系)。但这也表明客户并不关心合同:

public class Customer
{       
}

在这里您可以看到 Customer 类没有合同的(导航)属性。如果您不需要 Customer 对象来达成合同,这完全没问题。

现在如果你想拥有这种能力,你需要这样做:

public class Customer
{
   public List<Contract> Contracts { get; set; }       
}

modelBuilder.Entity<Contract>()
    .HasRequired(c => c.Customer)
    .WithMany(cu => cu.Contracts)

在这种情况下,您表明 Contract 与 Customer 之间存在某种关系,而从 Customer 对象的角度来看,这种关系会导致“Contracts”属性。