C#,实体框架 - IsRequired() 与 OnDelete()

问题描述 投票:0回答:1

请解释一下

ef core
中C#编程语言中的这些方法是否可以互换:

IsRequired()
OnDelete()

它们互相冲突吗?我可以只使用其中一种方法来实现我的目标吗?

据我了解,

OnDelete()
方法更广泛,我可以在所有情况下都只使用它而不是
IsRequired()
吗?

即:在这里,当使用

true
时,我不能在
IsRequired()
中使用
SetNull
,但如果我根本不写
IsRequired()
一切正常:

modelBuilder.Entity<User>()
      .HasOne(b => b.Biography)
      .WithOne(u => u.User)
      .HasForeignKey<Biography>(u => u.UserId)
      .IsRequired(false)
      .OnDelete(DeleteBehavior.SetNull);
  

如果我错了,请举例说明其中

IsRequired()
是强制性的,而只有
OnDelete()
没有帮助。

c# entity-framework entity-framework-core
1个回答
0
投票

IsRequired()
OnDelete()
相互影响,但不严格可互换。有 7 种不同的
DeleteBehaviour
值,而
IsRequired
只有 2 种状态,因此根据传入
IsRequired(bool)
的值,默认约定仅配置 2 种状态。

  • 使用
    IsRequired()
    根本不是强制性的,如果省略,则会通过关联属性类型的 nullability 来推断。如果该属性是 nullable,则隐含
    IsRequired(false)
    ,否则隐含
    IsRequired(true)

如果您的用例符合默认约定,那么您根本不需要一起指定

IsRequired()
OnDelete()
。您可能仍然选择这样做来明确您的意图,但是添加了约定的概念,以便您可以在一个地方做出全局决策,并减少代码中对此类规则的引用,这些规则变得更难以维护。

那么这会如何影响

OnDelete()

请参阅删除行为

Cascade
当主体被删除或与主体的关系被切断时,自动删除依赖实体,并在启用级联删除的情况下在数据库中创建外键约束。 这是所需关系的默认设置。

`ClientSetNull' 当对跟踪实体进行更改时,根据需要将外键值设置为 null,并在数据库中创建非级联外键约束。这是可选关系的默认设置。

根据 EF 中的默认约定(您可以覆盖),当 FK 通过 IsRequired(true) 标记为

required
时,级联删除将成为删除相关主体记录时的默认行为。

  • 您不能使用
    IsRequired(true)
    DeleteBehaviour.SetNull
    ,因为这没有意义,第一个语句表示不允许使用
    null
    ,第二个语句尝试强制分配
    null
    值。

如果您选择通过

IsRequired(false)
使 FK 可选,则默认
OnDelete()
DeleteBehaviour.ClientSetNull
。这意味着当主体实体被删除时,只有删除之前上下文中加载的实体的 FK 才会设置为 null。如果数据库中存在引用相同 FK 值的其他记录,当您尝试保存更改时,由于数据库引用约束违规,它将失败。

如果您希望数据库主动为数据库中引用相同 FK 值的所有其他记录设置 FK,那么我们必须指定

OnDelete(DeleteBehavior.SetNull)
向将执行此清理逻辑的数据库添加约束。

IsRequired(bool)
通常不需要与
OnDelete()
一起使用,但这只是由于您对 FK 属性的可为空性进行了智能设置。如果您为 FK 使用影子属性,那么
IsRequired()
确实是 required,但除此之外,标准约定是使用 FK 的可空性。

© www.soinside.com 2019 - 2024. All rights reserved.