EF Core - 为啥 ClientSetNull 是可选关系的默认 OnDelete 行为(而不是 SetNull)
Posted
技术标签:
【中文标题】EF Core - 为啥 ClientSetNull 是可选关系的默认 OnDelete 行为(而不是 SetNull)【英文标题】:EF Core - why ClientSetNull is default OnDelete behavior for optional relations (rather than SetNull)EF Core - 为什么 ClientSetNull 是可选关系的默认 OnDelete 行为(而不是 SetNull) 【发布时间】:2019-06-16 23:30:49 【问题描述】:对于可选关系(当外键可以接受 Null
时),自 EF Core 2.0 以来引入了新的 ClientSetNull
行为作为删除行为 DeleteBehavior.ClientSetNull
的 默认 选项。
这对跟踪的实体具有 SetNull
语义,对于未加载到内存中的数据库记录具有 Restrict
(无操作)行为。
Microsoft docs 这么说:
如果您希望数据库也尝试将空值传播给子项 即使没有加载子实体,外键也可以使用
SetNull
。但是,请注意,数据库必须支持这一点,并且 像这样配置数据库可能会导致其他限制, 这在实践中常常使这个选项不切实际。这就是为什么 SetNull 不是默认值。
但我认为当关联的父级被删除时(数据库中的每个位置),将依赖实体的 FK 设置为 Null 通常是正常的。而且,如上所述,那些“其他限制,在实践中常常使这个选项不切实际..”是什么?
【问题讨论】:
【参考方案1】:据我所知,文档所指的其他限制是循环或多路径级联。
例如,MS Sql Server 不允许级联(删除和设置 null)如果
更改将级联到它源自的同一个表 同一个表有多个级联路径。就像表“A”会影响表“B”和“C”一样,“B”和“C”都会影响“D”。你甚至不能创建约束。
EF 核心可以通过 ClientSetNull 绕过这个限制。 EF 处理 set null 操作,但只有在所有受影响的实体都加载到内存时才能这样做。
【讨论】:
感谢您的回答,虽然我投了赞成票,但我认为您在此处指定的情况很少见,仅将其设为默认选项是不够的!以上是关于EF Core - 为啥 ClientSetNull 是可选关系的默认 OnDelete 行为(而不是 SetNull)的主要内容,如果未能解决你的问题,请参考以下文章
为啥 EF Core 2.0 会生成多个重复的 SQL 语句?
为啥 EF Core 最后要添加一个额外的 ORDER BY
为啥 EF Core 2.2 总是更新“AspNetUsers”表中的“ConcurrencyStamp”、“PasswordHash”?