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

EFCore nullable relationship setting onDelete: ReferentialAction.Restrict

我是 运行 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);
            });

为什么它生成 onDelete: ReferentialAction.Restrict 当文档说它应该作为 ClientSetNull[=14 处理时=]

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

Behavior Name | Effect on dependent/child in memory | Effect on dependent/child in database

ClientSetNull (Default) | Foreign key properties are set to null | None

Changes in EF Core 2.0: In previous releases, Restrict would cause optional foreign key properties in tracked dependent entities to be set to null, and was the default delete behavior for optional relationships. In EF Core 2.0, the ClientSetNull was introduced to represent that behavior and became the default for optional relationships. The behavior of Restrict was adjusted to never have any side effects on dependent entities.

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

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

这是当前映射:

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

在您的例子中,关系是 optional,因此 DeleteBehavior 按照约定是 ClientSetNull,它映射到 onDelete: Restrict,或者换句话说,enforced(启用)FKw/o级联删除。

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

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