EFCore 可为空的关系设置 onDelete:ReferentialAction.Restrict

Posted

技术标签:

【中文标题】EFCore 可为空的关系设置 onDelete:ReferentialAction.Restrict【英文标题】:EFCore nullable relationship setting onDelete: ReferentialAction.Restrict 【发布时间】:2018-07-09 08:51:37 【问题描述】:

我正在运行 efcore 2.0.1。

我有一个模型:

public class BigAwesomeDinosaurWithTeeth

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id  get; set; 

    public ICollection<YummyPunyPrey> YummyPunyPrey  get; set; 

public class YummyPunyPrey

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id  get; set; 
    public Guid? BigAwesomeDinosaurWithTeethId  get; set; 

    [ForeignKey("BigAwesomeDinosaurWithTeethId")]
    public BigAwesomeDinosaurWithTeeth BigAwesomeDinosaurWithTeeth  get; set; 


我对这两个类没有流利的 api。但是当我生成迁移时

constraints: table =>
            
                table.PrimaryKey("PK_YummyPunyPrey", x => x.Id);
                table.ForeignKey(
                    name: "FK_YummyPunyPrey_BigAwesomeDinosaurWithTeeth_BigAwesomeDinosaurWithTeethId",
                    column: x => x.BigAwesomeDinosaurWithTeethId,
                    principalTable: "BigAwesomeDinosaurWithTeeth",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
            );

当文档说它应该将其作为 ClientSetNull

处理时,为什么会生成 onDelete: ReferentialAction.Restrict

https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete

行为名称|对内存中的依赖/子项的影响|对数据库中的依赖项/子项的影响

ClientSetNull(默认)|外键属性设置为空|

EF Core 2.0 中的更改:在以前的版本中,Restrict 会导致被跟踪的依赖实体中的可选外键属性设置为 null,并且是可选关系的默认删除行为。在 EF Core 2.0 中,引入了 ClientSetNull 来表示该行为,并成为可选关系的默认值。 Restrict 的行为已调整为不会对依赖实体产生任何副作用。

任何关于为什么会发生这种情况的帮助将不胜感激。

【问题讨论】:

【参考方案1】:

EF Core 2.0.1 元数据和迁移使用不同的枚举来指定删除行为 - 分别为 DeleteBehaviorReferentialAction。虽然第一个有据可查,但第二个和两者之间的映射没有(在撰写本文时)。

这是当前的映射:

DeleteBehavior    ReferentialAction
==============    =================
Cascade           Cascade
ClientSetNull     Restrict
Restrict          Restrict
SetNull           SetNull

在您的情况下,关系是optional,因此按照约定,DeleteBehavior 是映射到onDelete: RestrictClientSetNull,或者换句话说,强制(启用)FK w /o 级联删除。

如果你想要不同的行为,你必须使用流畅的 API,例如

modelBuilder.Entity<BigAwesomeDinosaurWithTeeth>()
    .HasMany(e => e.YummyPunyPrey)
    .WithOne(e => e.BigAwesomeDinosaurWithTeeth)
    .OnDelete(DeleteBehavior.SetNull); // or whatever you like

【讨论】:

应该为您制作金色雕像;谢谢伊万!文档真的让我失望了。我试图避免使用 API,但我已经多次破坏该解决方案,所以另一个不会受到伤害。

以上是关于EFCore 可为空的关系设置 onDelete:ReferentialAction.Restrict的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 EF Core 在可为空的列上创建筛选索引

如何在 VB.NET 中将可为空的 DateTime 设置为空?

序列化一个可为空的 int

为啥 TargetNullValue 更新可为空的 Source

如何使用 typeorm 将可为空的数据库字段设置为 NULL?

EF Core - 为啥 ClientSetNull 是可选关系的默认 OnDelete 行为(而不是 SetNull)