Efcore: EF Core 5 many-to-many specify on delete no action

Created on 28 Sep 2020  路  7Comments  路  Source: dotnet/efcore

Ask a question

In EF Core 5 many to many relationship I have a case that I need to specify Delete no action. How can I do that without creating the join table my self?

Include provider and version information

EF Core version: 5.0 RC2 Daily builds
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .Net Core 3.1
Operating system: Win 10
IDE: Latest VS2019

closed-could-not-reproduce customer-reported

Most helpful comment

@iSoap Since you have a relationship cycle in your model there's no good candidate for EF to make not cascade, so you'll have to choose one and configure it manually:

C# protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<FloorRoutine>() .HasMany(f => f.GymnastGroups) .WithMany(g => g.FloorRoutines) .UsingEntity<Dictionary<string, object>>( "GymnastGroupFloorRoutine", j => j.HasOne<GymnastGroup>().WithMany().OnDelete(DeleteBehavior.Cascade), j => j.HasOne<FloorRoutine>().WithMany().OnDelete(DeleteBehavior.ClientCascade)); }

We'll make this easier to do with #21535

All 7 comments

@pantonis Can you give some details on why you would want to do this? For typical join tables. the two entities cannot be related if one of them does not exist.

Because I have self referencing m2m and causes cyclic references

@pantonis EF should build a model without cascading action by convention for self-referencing many-to-many relationships. Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

EF Team Triage: This issue is lacking enough information for us to be able to effectively triage it. In particular, it is missing the following information requested in the new issue template. Can you please provide this information?

Steps to reproduce

Ideally include a complete code listing that we can run to reproduce the issue.

Alternatively, you can provide a project/solution that we can run.

BTW we're not just doing this to be mean :smile:... we get a lot traffic on this project and it takes time to attempt to reproduce an issue based on fragments of information. In addition, our attempt is often unsuccessful as the exact conditions required to hit the issue are often not explicitly included in the code provided. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we ask that folks give us a self-contained way to reproduce an issue.

For a guide on submitting good bug reports, read Painless Bug Tracking.

BTW this is a canned response and may have info or details that do not directly apply to this particular issue. While we'd like to spend the time to uniquely address every incoming issue, we get a lot traffic on the EF projects and that is not practical. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we use canned responses for common triage decisions.

Sorry for late reply. I simplified the database and I can't reproduce it anymore.

Hi. I have gotten the same "may cause cycles or multiple cascade paths" error, and has made a project to show it.
I am using ASP.NET Core 5 and EF Core 5
Here is the project on GitHub

My 3 models are

public class Team
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public string Name { get; set; }

    public ICollection<GymnastGroup> GymnastGroups { get; set; }

    public ICollection<FloorRoutine> FloorRoutines { get; set; }
}
public class GymnastGroup
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public Guid TeamId { get; set; }

    public string Name { get; set; }

    public Team Team { get; set; }

    public ICollection<FloorRoutine> FloorRoutines { get; set; }
}
public class FloorRoutine
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    public Guid TeamId { get; set; }

    public string Name { get; set; }

    public Team Team { get; set; }

    public string SongName { get; set; }

    public ICollection<GymnastGroup> GymnastGroups { get; set; }
}



md5-884625fad470680947fc70b5013107a1



migrationBuilder.CreateTable(
    name: "FloorRoutineGymnastGroup",
    columns: table => new
    {
        FloorRoutinesId = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
        GymnastGroupsId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_FloorRoutineGymnastGroup", x => new { x.FloorRoutinesId, x.GymnastGroupsId });
        table.ForeignKey(
            name: "FK_FloorRoutineGymnastGroup_FloorRoutines_FloorRoutinesId",
            column: x => x.FloorRoutinesId,
            principalTable: "FloorRoutines",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
        table.ForeignKey(
            name: "FK_FloorRoutineGymnastGroup_GymnastGroups_GymnastGroupsId",
            column: x => x.GymnastGroupsId,
            principalTable: "GymnastGroups",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    });

I could just remove the connection between the two classes I know, but I just want to know if it is intended to be like this.
Can I somehow tell the property that it should cascade on delete?

@iSoap Since you have a relationship cycle in your model there's no good candidate for EF to make not cascade, so you'll have to choose one and configure it manually:

C# protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<FloorRoutine>() .HasMany(f => f.GymnastGroups) .WithMany(g => g.FloorRoutines) .UsingEntity<Dictionary<string, object>>( "GymnastGroupFloorRoutine", j => j.HasOne<GymnastGroup>().WithMany().OnDelete(DeleteBehavior.Cascade), j => j.HasOne<FloorRoutine>().WithMany().OnDelete(DeleteBehavior.ClientCascade)); }

We'll make this easier to do with #21535

Was this page helpful?
0 / 5 - 0 ratings