1

I am using Entity Framework Core 6.0 and SQL Server.

I am trying to update a relational database to reflect this diagram: ER Diagram where a single red line over a relationship represents ON DELETE CASCADE and a double red line represents ON DELETE SET NULL.

The Users table is related to Groups in two different ways:

  • many-to-many through UserGroups which shows which users belongs to which hroups
  • one-to-many through Group.GroupCreatorID which stores the ID of the user that created the group

As far as I am aware, this setup means I need to have a delete property on the GroupCreator foreign key that tells it not to delete a user's groups if the user gets deleted, in order to prevent multiple cascading deletes from reaching a UserGroup.

To do this, I used the Fluent API in the DbContext to configure the relationship like so:

// N-N relationship between Users and Groups
modelBuilder.Entity<ApplicationUser>()
            .HasMany(u => u.Groups)
            .WithMany(g => g.Users);

// 1-N relationship - one user can create many groups
modelBuilder.Entity<Group>()
            .HasOne(g => g.GroupCreator)
            .WithMany(u => u.CreatedGroups)
            .HasForeignKey(g => g.GroupCreatorID)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.SetNull);

modelBuilder.Entity<Group>()
            .ToTable("Group");

Using the Package Manager Console I can create a migration successfully that has this in the Up method:

migrationBuilder.DropForeignKey(
                name: "FK_Group_AspNetUsers_GroupCreatorID",
                table: "Group");

migrationBuilder.AddForeignKey(
                name: "FK_Group_AspNetUsers_GroupCreatorID",
                table: "Group",
                column: "GroupCreatorID",
                principalTable: "AspNetUsers",
                principalColumn: "Id",
                onDelete: ReferentialAction.SetNull);

However when I run Update-Database I get the following error:

fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER TABLE [Group] ADD CONSTRAINT [FK_Group_AspNetUsers_GroupCreatorId] FOREIGN KEY ([GroupCreatorId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE;

Failed executing DbCommand (12ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
ALTER TABLE [Group] ADD CONSTRAINT [FK_Group_AspNetUsers_GroupCreatorId] FOREIGN KEY ([GroupCreatorId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE;

It looks like it is still trying to use ON DELETE CASCADE even though I specifically set it otherwise.

I have tried using FluentAPI and making the field nullable in the model.

I have also tried changing the migrationBuilder.AddForeignKey() call in the migration's Up() method to migrationBuilder.Sql("ALTER TABLE[Group] ADD CONSTRAINT[FK_Group_AspNetUsers_GroupCreatorId] FOREIGN KEY([GroupCreatorId]) REFERENCES[AspNetUsers]([Id]) ON DELETE SET NULL"); and I get the same issue as before.

I can overwrite the ON DELETE section in the existing DDL statement that I find in the SQL Server Object Explorer, but I want to be able to continue to migrate to the database. As this is a school project I have to use a local database on multiple devices, which is suitable for my purposes so long as I can update it with a migration.

Sorry if this question is too long, I am not certain on how much information is necessary to provide, as I don't fully understand the problem. Thank you

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Gravy
  • 11
  • 2

0 Answers0