Disable cascade delete on EF Core 2 globally

Viewed 21505

I need to know about ways of disabling cascade delete in EF Core 2 globally. Any help is appricated.

In EF 6.x we used following code to disable cascade delete on both OneToMany and ManyToMany realtions:

builder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
builder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
3 Answers

Unfortunately EF Core currently (latest at this time v2.0) does not expose a good way to control the conventions globally.

The default EF Core 2.0 convention is to use DeleteBehavior.Cascade for required and DeleteBehavior.ClientSetNull for optional relationships. What I can suggest as workaround is a typical metadata model loop at the end of the OnModelCreating override. In this case, locating all the already discovered relationships and modifying them accordingly:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // ...

    var cascadeFKs = modelBuilder.Model.GetEntityTypes()
        .SelectMany(t => t.GetForeignKeys())
        .Where(fk => !fk.IsOwnership && fk.DeleteBehavior == DeleteBehavior.Cascade);

    foreach (var fk in cascadeFKs)
        fk.DeleteBehavior = DeleteBehavior.Restrict;

    base.OnModelCreating(modelBuilder);
}
constraints: table =>
                {
                    table.PrimaryKey("PK_ComandaPlato", x => x.ComandaPlatoId);
                    table.ForeignKey(
                        name: "FK_ComandaPlato_Comanda_ComandaId",
                        column: x => x.ComandaId,
                        principalTable: "Comanda",
                        principalColumn: "ComandaId",
                        onDelete: ReferentialAction.Cascade);//default: cascade on
                    table.ForeignKey(
                        name: "FK_ComandaPlato_Plato_PlatoId",
                        column: x => x.PlatoId,
                        principalTable: "Plato",
                        principalColumn: "PlatoId",
                        onDelete: ReferentialAction.NoAction);//turn off cascade,"by hand"
                });
//comments: modifing the auto-generated migration, "harcode by hand" this attibute, as view bellow: change "Cascade" to "NoAction" (as view 1st and 2st examples)

May be It helps:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
ChangeTracker.CascadeDeleteTiming = ChangeTracking.CascadeTiming.Never;
ChangeTracker.DeleteOrphansTiming = ChangeTracking.CascadeTiming.Never;
}
Related