更新数据库失败:“索引'IX_Task_UserId'取决于列'UserId'”

Nie*_*iek 4 asp.net asp.net-mvc entity-framework entity-framework-core asp.net-core

[required]注释添加到3个模型上的2个属性并运行后add-migration,运行时出现以下错误update-database

ALTER TABLE ALTER COLUMN UserId failed because one or more objects access this column. The index 'IX_Task_UserId' is dependent on column 'UserId'.

我的up()迁移如下所示:

protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_TaskList_AspNetUsers_UserId",
            table: "TaskList");

        migrationBuilder.DropForeignKey(
            name: "FK_Template_AspNetUsers_UserId",
            table: "Template");

        migrationBuilder.DropForeignKey(
            name: "FK_Task_AspNetUsers_UserId",
            table: "Task");

        migrationBuilder.AlterColumn<string>(
            name: "UserId",
            table: "Task",
            nullable: false);

        migrationBuilder.AlterColumn<string>(
            name: "TaskName",
            table: "Task",
            nullable: false);

        migrationBuilder.AlterColumn<string>(
            name: "UserId",
            table: "Template",
            nullable: false);

        migrationBuilder.AlterColumn<string>(
            name: "TemplateName",
            table: "Template",
            nullable: false);

        migrationBuilder.AlterColumn<string>(
            name: "UserId",
            table: "TaskList",
            nullable: false);

        migrationBuilder.AlterColumn<string>(
            name: "ListName",
            table: "TaskList",
            nullable: false);

        migrationBuilder.AddForeignKey(
            name: "FK_TaskList_AspNetUsers_UserId",
            table: "TaskList",
            column: "UserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_Template_AspNetUsers_UserId",
            table: "Template",
            column: "UserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_Task_AspNetUsers_UserId",
            table: "Task",
            column: "UserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    }
Run Code Online (Sandbox Code Playgroud)

我不确定错误指的是什么索引,也不确定为什么要删除外键(再次,我所做的就是使一些属性不可为空)。谢谢你的帮助。

Iva*_*oev 8

我所做的就是使一些属性不可为空

好吧,通常将非可空(必需)表列转换为可空(可选)表是没有问题的,但并非相反,因此最好事先仔细考虑。

这里的“小”问题是,少数几个属性中的大多数是外键,这使转换更加复杂。EF Core自动生成的迁移尝试通过在更改列之前删除FK约束并在之后重新创建约束来正确地解决此问题。不幸的是,FK约束通常具有关联的索引(如果找到为实例“ FK_Task_AspNetUsers_UserId”创建的迁移,则应该看到它还创建了索引“ IX_Task_UserId”),并且他们忘记删除并重新创建索引,这导致您收到的异常(来自数据库)。

因此,您需要手动修复生成的迁移(您可能还考虑将错误报告发布到EF Core存储库)。

为此,请在第一个AlterColumn调用之前插入以下内容:

migrationBuilder.DropIndex(
    name: "IX_Task_UserId",
    table: "Task");
Run Code Online (Sandbox Code Playgroud)

以及最后一次AlterColumn通话后的以下内容:

migrationBuilder.CreateIndex(
    name: "IX_Task_UserId",
    table: "Task",
    column: "UserId");
Run Code Online (Sandbox Code Playgroud)

这个问题应该解决。

请注意,您可能还需要对迁移中包含的其他表执行类似的操作,即类似这样的操作(请确保从相应的初始迁移中验证名称):

migrationBuilder.DropIndex(
    name: "IX_TaskList_UserId",
    table: "TaskList");

migrationBuilder.DropIndex(
    name: "IX_Template_UserId",
    table: "Template");
Run Code Online (Sandbox Code Playgroud)

然后:

migrationBuilder.CreateIndex(
    name: "IX_TaskList_UserId",
    table: "TaskList",
    column: "UserId");

migrationBuilder.CreateIndex(
    name: "IX_Template_UserId",
    table: "Template",
    column: "UserId");
Run Code Online (Sandbox Code Playgroud)