Creating an Entity with multiple one-to-many relationship and a DeleteBehavior

0

I'm using EntityFramework Core version 2.2.

I have three entities: Team, Player and Notes. Each team can have a note for each player, so a player may have multiple team that took a note on him. A note can have only one team and one player.

public class Team
{
    public int ID {get; set;}
    public ICollection<Note> Notes { get; set; }

    public ICollection<Player> Players { get; set; }
}
public class Player
{
    public int ID {get; set;}
    public ICollection<Note> Notes { get; set; }

    public int TeamID {get; set;}
    [ForeignKey("TeamID")]
    public Team Team {get; set;}
}
public class Note
{
    public int ID { get; set; }

    // Navigation property
    public int? PlayerID { get; set; }
    [ForeignKey("PlayerID")]
    public Player Player { get; set; }

    // Navigation property
    public int? TeamID { get; set; }
    [ForeignKey("TeamID")]
    public Team Team { get; set; }

    public string Text { get; set; }
}

In the intended behaviour, if a team or a player is removed from the database, any eventual note related to the team or the player must be removed. Moreover, typically I expect to search the note using the combination of PlayerID and the TeamID as search key. This is the reason why I added to the OnModelCreating of the ApplicationDbContext the following instructions:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<Note>()
        .HasKey(n => new { n.PlayerID, n.TeamID });
    builder.Entity<Team>()
        .HasMany(t => t.Notes)
        .WithOne(n => n.Team)
        .OnDelete(DeleteBehavior.Cascade);
    builder.Entity<Player>()
        .HasMany(n => n.Notes)
        .WithOne(w => w.Player)
        .OnDelete(DeleteBehavior.Cascade);
}

When I ask to add the new entity and the OnModelCreating rules to the database using EntityFramework command Add-Migration, everything seems ok generating the following Up-Migration:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.CreateTable(
        name: "Notes",
        columns: table => new
        {
            PlayerID = table.Column<int>(nullable: false),
            TeamID = table.Column<int>(nullable: false),
            Text = table.Column<string>(maxLength: 512, nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_Notes", x => new { x.PlayerID, x.TeamID });
            table.ForeignKey(
                name: "FK_Notes_Player_PlayerID",
                column: x => x.PlayerID,
                principalTable: "Player",
                principalColumn: "ID",
                onDelete: ReferentialAction.Cascade);
            table.ForeignKey(
                name: "FK_Notes_Team_TeamID",
                column: x => x.TeamID,
                principalTable: "Team",
                principalColumn: "ID",
                onDelete: ReferentialAction.Cascade);
        });

    migrationBuilder.CreateIndex(
        name: "IX_Notes_TeamID",
        table: "Notes",
        column: "TeamID");
}

When it's time to update the database with the migration, the Update-Database generates an error with the following SqlException (translated from Italian to English): System.Data.SqlClient.SqlException (0x80131904): FOREIGN KEY 'FK_Notes_Team_TeamID' in table 'Notes' may determine the creation of cycles or multiple propagation paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION or modify the other FOREIGN KEY constraint.

Following this StackOverflow post Entity Framework Code First 5 Cascade Delete on many to many tables error I understood that MsSql doesn't accept multiple OnDelete cascade constraints. I changed the code setting DeleteBehavior.ClientSetNull instead (and making int? the foreign keys PlayerID and TeamID), but I wonder if there is a method to create an automatic Notes delete function using EntityFramework when a Team or a player is deleted.

c#
entity-framework-core
asked on Stack Overflow May 10, 2020 by Leonardo Daga • edited May 10, 2020 by Leonardo Daga

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0