请解释一下
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()
没有帮助。
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 的可空性。