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

15

我正在使用 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://learn.microsoft.com/en-us/ef/core/saving/cascade-delete


行为名称 | 对内存中的相关/子级的影响 | 对数据库中的相关/子级的影响


ClientSetNull(默认) | 外键属性被设置为null | 无影响


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


1个回答

29
EF Core 2.0.1元数据和迁移使用不同的枚举来指定删除行为,分别是DeleteBehaviorReferentialAction。虽然第一个有很好的文档记录,但第二个和两者之间的映射没有(截至撰写本文时)。
以下是当前的映射:
DeleteBehavior    ReferentialAction
==============    =================
Cascade           Cascade
ClientSetNull     Restrict
Restrict          Restrict
SetNull           SetNull

在您的情况下,关系是可选的,因此按照惯例,DeleteBehaviorClientSetNull,它映射到onDelete: Restrict,换句话说,是强制执行的(启用)FK,没有级联删除。
如果您需要不同的行为,则必须使用流畅的API,例如:
modelBuilder.Entity<BigAwesomeDinosaurWithTeeth>()
    .HasMany(e => e.YummyPunyPrey)
    .WithOne(e => e.BigAwesomeDinosaurWithTeeth)
    .OnDelete(DeleteBehavior.SetNull); // or whatever you like

4
在你的荣誉中应该制作金色雕像;谢谢伊万!这份文档真的让我感到困惑。我原本想避免使用API,但我已经多次打破了这个决定,所以再违反一次也无妨。 - David Moores

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接