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

Understanding disabling on cascade delete using fluent api

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

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

我想了解很多部分:

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

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

级联删除

假设您的出勤率 link 是另一种类型。所以在数据库中,这种其他类型 (table) 将有一个指向 Attendance table.

的外键

如果您尝试删除数据table中的一条Attendance记录,但如果这条记录在其他table中被使用,它将失败。

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

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

实体

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

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

因此您可以警告 EF 此 table 在另一个架构中或 table 名称不同...

可能你可以为你所有的 entities/tables 做到这一点。

IsRequired(在你的例子中没有使用,但我认为 IsRequiredHasRequired 所以我在这里解释)

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

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

有要求

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

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

public class Customer
{       
}

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

此配置将指示合同有一个导航 属性 到客户,这是必需的,意味着外键不能为空。如果你希望它可以为空,你应该使用 HasOptional.

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

public class Customer
{       
}

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

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

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

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

在这种情况下,您表示合同与客户之间存在所需的关系,并且从客户对象的角度来看,这种关系导致“合同”属性。