asp.net - 更新数据库失败 : "The index ' IX_Task_UserId' is dependent on column 'UserId' "

标签 asp.net asp.net-mvc entity-framework asp.net-core entity-framework-core

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

ALTER TABLE ALTER COLUMN UserId 失败,因为一个或多个对象访问此列。 索引“IX_Task_UserId”依赖于列“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);
    }

我不确定错误指的是哪个索引,我也不完全理解为什么外键被删除(同样,我所做的只是使一些属性不可为空)。感谢您的帮助。

最佳答案

all I did was make a few properties non-nullable

嗯,通常将不可空(必需)表列转换为可空(可选)没有问题,但相反则不然,因此最好提前仔细考虑。

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

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

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

migrationBuilder.DropIndex(
    name: "IX_Task_UserId",
    table: "Task");

最后一次 AlterColumn 调用后的以下内容:

migrationBuilder.CreateIndex(
    name: "IX_Task_UserId",
    table: "Task",
    column: "UserId");

问题应该得到解决。

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

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

migrationBuilder.DropIndex(
    name: "IX_Template_UserId",
    table: "Template");

然后:

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

migrationBuilder.CreateIndex(
    name: "IX_Template_UserId",
    table: "Template",
    column: "UserId");

关于asp.net - 更新数据库失败 : "The index ' IX_Task_UserId' is dependent on column 'UserId' ",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41524928/

相关文章:

Visual Studio 2010 中带有 64 位程序集的 ASP.net 页面

c# - 在 .NET 中,如何防止或处理在提交前篡改禁用字段的表单数据?

ios - Web 应用程序在设备上的 iPad 和 iPhone 上崩溃,但在调试时不崩溃(Web 检查器)

c# - 如何让 EF6 生成高效的 in(...) 查询

c# - 如何使用通用存储库模式按类型有条件地过滤 IQueryable

asp.net - 在 visual studio 2008 [ASP.NET MVC] 中更改调试器的初始 url

ASP.NET LINQ 数据库供应商

ASP.NET 动态数据和成员资格(角色)

asp.net-mvc - 使用 Entity Framework 实现存储库模式。存储库范围内的问题解决实体

c# - 使 API 调用和数据库操作原子化