Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlServer Migrations: Rebuild foreign keys #20943

Closed
claudeHasler opened this issue May 13, 2020 · 5 comments
Closed

SqlServer Migrations: Rebuild foreign keys #20943

claudeHasler opened this issue May 13, 2020 · 5 comments

Comments

@claudeHasler
Copy link

I have an asp.net core / ef core project where im writing to a Microsoft SQL database.
I have relationships between several of models via foreign key constraints. I am now trying to update some primary keys, from nvarchar(50) to nvarchar(200) via generated migrations SQL script, but am constantly running into errors of this kind:

The object 'FK_Plans_Plans_ParentUid' is dependent on column 'Uid'.
Msg 4922, Level 16, State 9, Line 54
ALTER TABLE ALTER COLUMN Uid failed because one or more objects access this column.

I assume this is because of the foreign keys referencing my altered primary key.
I would expect ef core to first remove any FK constraints, then alter table, then reapply FK constraints, to avoid this conflict,but this is not happening.

Is this expected behaviour? Can i trigger this behaviour somehow? I can of course manipulate the migrations manually, but this seems error prone and very time consuming, seeing as i have quite a few FK constraints

Steps to reproduce

If this is not expected behaviour I will create a sample project I can share. My current project is sensitive and too large to share

Further technical details

EF Core version:3.1.4
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: netcoreapp3.1
Operating system: Windows 10
IDE: Visual Studio 2019

@ajcvickers
Copy link
Member

I would expect ef core to first remove any FK constraints, then alter table, then reapply FK constraints, to avoid this conflict,but this is not happening.

This is what should be happening, so there may be a bug or something else preventing it in your case. Sample project would be great!

@claudeHasler
Copy link
Author

claudeHasler commented May 13, 2020

https://gofile.io/d/UOaXwT
here you will find the project. Althaus.Tracker.Server is the ASP.NET Core server. I am changing the PlanDM and SerialDM UIDs from [StringLength(200)] to [StringLength(300)], creating a new migration and then generating the sql script. Thanks!

@ajcvickers
Copy link
Member

@bricelam I am able to reproduce this. The migration generates simple AlterColumn calls for the key length, but this fails.

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<string>(
        name: "PlanUid",
        table: "PlanSerialNumbers",
        nullable: true,
        oldClrType: typeof(string),
        oldType: "nvarchar(200)",
        oldNullable: true);

    migrationBuilder.AlterColumn<string>(
        name: "ParentUid",
        table: "Plans",
        nullable: true,
        oldClrType: typeof(string),
        oldType: "nvarchar(200)",
        oldNullable: true);

    migrationBuilder.AlterColumn<string>(
        name: "Uid",
        table: "Plans",
        maxLength: 300,
        nullable: false,
        oldClrType: typeof(string),
        oldType: "nvarchar(200)",
        oldMaxLength: 200);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<string>(
        name: "PlanUid",
        table: "PlanSerialNumbers",
        type: "nvarchar(200)",
        nullable: true,
        oldClrType: typeof(string),
        oldNullable: true);

    migrationBuilder.AlterColumn<string>(
        name: "ParentUid",
        table: "Plans",
        type: "nvarchar(200)",
        nullable: true,
        oldClrType: typeof(string),
        oldNullable: true);

    migrationBuilder.AlterColumn<string>(
        name: "Uid",
        table: "Plans",
        type: "nvarchar(200)",
        maxLength: 200,
        nullable: false,
        oldClrType: typeof(string),
        oldMaxLength: 300);
}

@bricelam
Copy link
Contributor

bricelam commented May 26, 2020

I don't think we rebuild foreign keys--only indexes the moment:

indexesToRebuild = GetIndexesToRebuild(column, operation).ToList();
DropIndexes(indexesToRebuild, builder);

But yes, we should do this.

I vaguely remember talking about it before (possibly in EF6) and it was kind of dangerous at the time because we didn't always have the ON DELETE behavior, but I think we can handle this a lot better now. (e.g. only rebuild FKs if they're in the backing model) Note however, that we still don't have the ON UPDATE behavior in the model, so this would be lost.

@bricelam bricelam changed the title Foreign key conflict when changing primary key datatype with migrations Migrations: Rebuild foreign key when column altered May 29, 2020
@bricelam bricelam self-assigned this May 29, 2020
@bricelam bricelam changed the title Migrations: Rebuild foreign key when column altered SqlServer Migrations: Rebuild foreign keys May 29, 2020
@ajcvickers ajcvickers added this to the Backlog milestone May 30, 2020
@bricelam
Copy link
Contributor

Duplicate of #12586

@bricelam bricelam marked this as a duplicate of #12586 Aug 20, 2020
@bricelam bricelam removed their assignment Aug 20, 2020
@bricelam bricelam removed this from the Backlog milestone Aug 20, 2020
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants