EF Core migration generated `ReferentialAction.Restrict` but in context set as `DeleteBehavior.ClientSetNull`

c# entity-framework-core sql-server


I discover this while I tried to run my delete query when it stop my with the error

The DELETE statement conflicted with the REFERENCE constraint "FK_List_ListId"

When I through an analysis to the issue, noticed that in the latest migration onDelete: ReferentialAction.Restrict. But I have generated this migration after set .OnDelete(DeleteBehavior.ClientSetNull).

Below by sample tables and their relationships:

public class List
    public int ListId { get; set; }
    public string ListName { get; set; }
    public ICollection<Task> Tasks { get; set; }

public class Task
    public int TaskId { get; set; }
    public string TaskName { get; set; }
    public string Description { get; set; }
    public int? ListId { get; set; }
    public List List { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
        .HasOne(x => x.List)
        .WithMany(y => y.Tasks)
        .HasForeignKey(z => z.ListId)

Migration code generated as:

protected override void Up(MigrationBuilder migrationBuilder)
        name: "FK_List_ListId",
        table: "Tasks");

        name: "FK_List_ListId",
        table: "Tasks",
        column: "ListId",
        principalTable: "Lists",
        principalColumn: "ListId",
        onDelete: ReferentialAction.Restrict);

In migration onDelete: ReferentialAction.Restrict but should not it be onDelete: ReferentialAction.SetNull. I am not sure what I did wrong while creating the relationship.

3/31/2020 5:36:22 PM

Accepted Answer

EF Core 2.0.1 metadata and migrations use different enums for specifying the delete behavior - respectively DeleteBehavior and ReferentialAction. While the first is well documented, the second and the mapping between the two is not (at the time of writing).

Here is the current mapping:

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

In your case, the relationship is optional, hence the DeleteBehavior by convention is ClientSetNull which maps to onDelete: Restrict, or in other words, enforced (enabled) FK w/o cascade delete.

If you want different behavior, you have to use fluent API, e.g.

    .HasMany(e => e.YummyPunyPrey)
    .WithOne(e => e.BigAwesomeDinosaurWithTeeth)
    .OnDelete(DeleteBehavior.SetNull); // or whatever you like
1/30/2018 1:58:18 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow