【问题标题】:EF Core sets the Foreign Key constraint as 'ON DELETE RESTRICT' even though the FK is nullableEF Core 将外键约束设置为“ON DELETE RESTRICT”,即使 FK 可以为空
【发布时间】:2021-09-10 21:04:36
【问题描述】:

我正在使用 Npgsql 和 PostgreSQL 一起使用 EF Core,并且我已将依赖实体的外键(章节,见下文)设置为可为空的 int。当我删除主体实体(在本例中为 Book)时,我期待 CASCADE NULL 会发生。相反,在迁移中,行为是 ON DELETE RESTRICT。所以当我尝试删除它抛出的 Book 实体时

对表“Books”的更新或删除违反了对表“Chapters”的外键约束“FK_Chapters_Books_BookId”

默认情况下不应该是ON DELETE SET NULL吗?如何设置为 SET NULL?

包含您的代码

图书实体:

[Index(nameof(ISBN))]
public class Book
{
    public int BookId { get; set; }

    public string ISBN { get; set; }

    public List<Chapter> Chapters { get; set; }
}

章节实体:


public class Chapter
{
    public int ChapterId { get; set; }

    public string Title { get; set; }

    public int? BookId { get; set; }    //  <--- nullable
    public Book Book { get; set; }
}

为章节实体生成的迁移:


migrationBuilder.CreateTable(
    name: "Chapters",
    columns: table => new
    {
        ChapterId = table.Column<int>(type: "integer", nullable: false)
            .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
        Title = table.Column<string>(type: "text", nullable: true),
        BookId = table.Column<int>(type: "integer", nullable: true),
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Chapters", x => x.ChapterId);
        table.ForeignKey(
            name: "FK_Chapters_Books_BookId",
            column: x => x.BookId,
            principalTable: "Books",
            principalColumn: "BookId",
            onDelete: ReferentialAction.Restrict);         // <---  Why??????
    });

正如您在上面看到的,onDelete: ReferentialAction.Restrict) 中有限制。为什么不默认SetNull

包括堆栈跟踪

Message: 
    Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
    ---- Npgsql.PostgresException : 23503: update or delete on table "Books" violates foreign key constraint "FK_Chapters_Books_BookId" on table "Chapters"
  Stack Trace: 
    ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
    BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
    RelationalDatabase.SaveChanges(IList`1 entries)
    StateManager.SaveChanges(IList`1 entriesToSave)
    StateManager.SaveChanges(DbContext _, Boolean acceptAllChangesOnSuccess)
    NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
    StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
    DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
    DbContext.SaveChanges()
    BookServicesTests.RegisterNewBook_CanSuccessfullySaveToDatabase() line 63
    --- End of stack trace from previous location ---
    ----- Inner Stack Trace -----
    NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
    NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
    NpgsqlDataReader.NextResult()
    NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
    NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
    NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
    NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
    DbCommand.ExecuteReader()
    RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
    ReaderModificationCommandBatch.Execute(IRelationalConnection connection)

包括提供者和版本信息

  • EF Core 版本:5.0.4
  • 数据库提供者:Npgsql.EntityFrameworkCore.PostgreSQL
  • 目标框架:.NET 5.0
  • 操作系统:Windows 10
  • IDE:Visual Studio 2019 16.10)

【问题讨论】:

标签: c# postgresql entity-framework-core npgsql


【解决方案1】:

这不起作用,因为章节模型作为外键的 Book 模型中的数据库列本身不是可为空的类型。

我认为您的架构本身是不正确的。您不需要将 BookId 字段设置为可为空的类型,因为文字书中的所有章节都必须属于代码中的书。

尝试更正该架构错误。

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-16
    • 2011-10-06
    • 1970-01-01
    • 2020-10-18
    • 2021-10-27
    • 1970-01-01
    • 2021-11-08
    • 2021-09-03
    相关资源
    最近更新 更多