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