EF Core DeleteBehavior.SetNull會產生循環問題

.net-core entity-framework-core

我正在使用EF Core 1.1.0,我有一個嚴重的級聯行為問題。

我有一個名為Land的模型如下:

public class Land
{
    public long Id { get; set; }
    public int HorizontalPosition { get; set; }
    public int VerticalPosition { get; set; }
    public bool IsPlaced { get; set; }

    // Relations
    public string UserId { get; set; }
    public virtual User User { get; set; }
    public long? BuildingId { get; set; }
    public virtual Building Building { get; set; }
}

和另一個名為Building的模型如下:

public class Building
{
    public long Id { get; set; }
    public bool IsPermanent { get; set; }
    public int UpgradeCount { get; set; }

    // Relations
    public string UserId { get; set; }
    public virtual User User { get; set; }
    public int BuildingTypeId { get; set; }
    public virtual BuildingType BuildingType { get; set; }
    public virtual List<Land> Lands { get; set; }
}

在dbcontext中我提到了一個關係:

...
modelBuilder.Entity<Land>()
            .HasOne(l => l.Building)
            .WithMany(b => b.Lands)
            .HasForeignKey(l => l.BuildingId)
            .OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.SetNull);
...

但是當我嘗試更新數據庫時,我收到此錯誤:

System.Data.SqlClient.SqlException: Introducing FOREIGN KEY constraint 'FK_Lands_Buildings_BuildingId' on table 'Lands' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:65b8e08e-2d17-46ac-b734-385f88dd07b1
Error Number:1785,State:0,Class:16
Introducing FOREIGN KEY constraint 'FK_Lands_Buildings_BuildingId' on table 'Lands' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.

生成的遷移是這樣的:

...
migrationBuilder.AddForeignKey(
            name: "FK_Lands_Buildings_BuildingId",
            table: "Lands",
            column: "BuildingId",
            principalTable: "Buildings",
            principalColumn: "Id",
            onDelete: ReferentialAction.SetNull);
...

我已經告訴過,在刪除時將外鍵設置為null但是它要我不做任何操作。雖然在dbcontext中沒有名為'NoAction'的行為!

行為選擇

熱門答案

您看到的異常文本由SQL Server生成。

EF Core沒有任何相同的NO ACTION

您唯一的方法是將Restrict設置為一個引用(或兩者)。

在刪除父實體( User )之前,您需要手動管理相關記錄(例如更新或刪除Lands )。或者,在渲染視圖時檢查子記錄是否存在,並且不顯示用於刪除用戶的鏈接/按鈕。或者在刪除,中止操作期間捕獲異常並向用戶顯示相關消息。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow