Dopo aver aggiunto un'annotazione [required]
a 2 proprietà su 3 modelli ed eseguendo add-migration
, ottengo il seguente errore durante l'esecuzione di 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'.
La mia migrazione up () ha il seguente aspetto:
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);
}
Non sono sicuro di quale sia l'indice a cui si riferisce l'errore, né comprendo appieno il motivo per cui le chiavi esterne vengono eliminate (di nuovo, tutto ciò che ho fatto è stato rendere alcune proprietà non annullabili). Grazie per qualsiasi aiuto.
tutto ciò che ho fatto è stato rendere alcune proprietà non annullabili
Bene, di solito non vi è alcun problema nel convertire una colonna di tabella non nullable (richiesta) in nullable (opzionale), ma non nell'opposto, quindi è bene pensare con attenzione in anticipo.
Il "piccolo" problema qui è che la maggior parte delle poche proprietà sono chiavi esterne, il che complica ulteriormente la conversione. La migrazione generata automaticamente da EF Core tenta di gestirla correttamente rimuovendo i vincoli FK prima di alterare la colonna e ricrearli dopo. Sfortunatamente il vincolo FK di solito ha un indice associato (se trovi la migrazione che ha creato per esempio "FK_Task_AspNetUsers_UserId", dovresti vedere che crea anche un indice "IX_Task_UserId"), e dimenticano di eliminare e ricreare anche l'indice, il che porta a l'eccezione che stai ricevendo (proviene dal database).
Quindi è necessario correggere manualmente la migrazione generata (si potrebbe anche considerare di postare una segnalazione di bug nel repository EF Core).
Per fare ciò, inserisci quanto segue prima della prima chiamata AlterColumn
:
migrationBuilder.DropIndex(
name: "IX_Task_UserId",
table: "Task");
e il seguente dopo l'ultima chiamata AlterColumn
:
migrationBuilder.CreateIndex(
name: "IX_Task_UserId",
table: "Task",
column: "UserId");
e il problema dovrebbe essere risolto.
Nota che potrebbe essere necessario fare lo stesso per le altre tabelle incluse nella migrazione, ad esempio qualcosa di simile (assicurati di verificare i nomi dalla migrazione iniziale corrispondente):
migrationBuilder.DropIndex(
name: "IX_TaskList_UserId",
table: "TaskList");
migrationBuilder.DropIndex(
name: "IX_Template_UserId",
table: "Template");
e poi:
migrationBuilder.CreateIndex(
name: "IX_TaskList_UserId",
table: "TaskList",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_Template_UserId",
table: "Template",
column: "UserId");