Asp.net

更新數據庫失敗:“索引 ‘IX_Task_UserId’ 依賴於列 ‘UserId’”

  • January 8, 2017

為 3 個模型上的 2 個屬性添加[required]註釋並執行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);
   }

我不確定錯誤指的是什麼索引,我也不完全理解為什麼要刪除外鍵(同樣,我所做的只是使一些屬性不可為空)。謝謝你的幫助。

我所做的只是使一些屬性不可為空

好吧,通常將不可為空(必需)的表列轉換為可空(可選)是沒有問題的,但反之亦然,因此最好提前仔細考慮。

這裡的“小”問題是少數幾個屬性中的大多數都是外鍵,這也使轉換變得複雜。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");

引用自:https://stackoverflow.com/questions/41524928