【问题标题】:Self-referencing in EF core Error: the insert statement conflicted with the foreign key same table constraintEF核心中的自引用错误:插入语句与外键同表约束冲突
【发布时间】:2020-08-17 15:20:20
【问题描述】:

我有一个带有自引用的 Category 模型,并且在创建数据库时工作正常,但是当我尝试插入父类别(没有 parentId 的实体)时,我收到指向外键“ParentId”的错误,但是当我在 SSMS 中使用插入脚本手动插入 topel 并在添加子类别(具有 parentId 的实体)时与 ef core 一起正常工作时,它工作正常

类别模型

public class Category : ICategory
{
    public Category()
    {
    }

    [Key]
    public int Id { get; set; }

    [Required]
    [MinLength(2)]
    [MaxLength(32)]
    public string Title { get; set; }

    public string Icon { get; set; }

    [DefaultValue(true)]
    public bool IsEnabled { get; set; }

    [Required]
    public DateTime CreateTimeStamp { get; set; }

    public DateTime LastUpdateTimeStamp { get; set; }

    [ForeignKey("User")]
    public int CreatorUserId { get; set; }
    
    public int? ParentId { get; set; }

    public virtual User User { get; set; }
    
    [ForeignKey("ParentId")]
    public virtual Category Parent { get; set; }
    public virtual ICollection<Category> Children { get; set; }
    public virtual ICollection<Service> Services { get; set; }
}

数据库上下文

public DbSet<Category> Categories { get; set; }

modelBuilder.Entity<Category>(entity =>
        {
            entity.HasIndex(e => e.Title).IsUnique();
            entity.HasOne(e => e.User).WithMany(e => e.CreatedCategories)
                .HasForeignKey(e => e.CreatorUserId).OnDelete(DeleteBehavior.Restrict);
            entity.HasOne(e => e.Parent).WithMany(e => e.Children).HasForeignKey(e => e.ParentId).IsRequired(false);
        });

迁移

protected override void Up(MigrationBuilder migrationBuilder)
{
        migrationBuilder.CreateTable(
            name: "Categories",
            columns: table => new
            {
                Id = table.Column<int>(nullable: false)
                    .Annotation("SqlServer:Identity", "1, 1"),
                Title = table.Column<string>(maxLength: 32, nullable: false),
                Photo = table.Column<string>(nullable: true),
                IsEnabled = table.Column<bool>(nullable: false),
                CreateTimeStamp = table.Column<DateTime>(nullable: false),
                LastUpdateTimeStamp = table.Column<DateTime>(nullable: false),
                CreatorUserId = table.Column<int>(nullable: false),
                ParentId = table.Column<int>(nullable: true)
            }
            constraints: table =>
            {
                table.PrimaryKey("PK_Categories", x => x.Id);
                table.ForeignKey(
                    name: "FK_Categories_Users_CreatorUserId",
                    column: x => x.CreatorUserId,
                    principalTable: "Users",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
                table.ForeignKey(
                    name: "FK_Categories_Categories_ParentId",
                    column: x => x.ParentId,
                    principalTable: "Categories",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Restrict);
            });
}

无论如何我都可以将“ParentId”标记为可为空,但尽管 SQL Server 没有问题,但核心阻止了我!

错误信息内部异常:

INSERT 语句与 FOREIGN KEY SAME TABLE 约束“FK_Categories_Categories_ParentId”冲突。冲突发生在数据库“Unknown_Db”、表“dbo.Categories”、“Id”列中。

【问题讨论】:

  • 可以添加错误信息吗?
  • 您使用的是哪个版本的 C# 和 EFC?
  • 能否包含 EF Core 命令日志?使用Parent = nullParentId = null 添加新类别应该可以,因此示例模型/配置中必须缺少某些内容,或者数据库与迁移所指示的不同。
  • 你能显示在迁移过程中创建的外键吗? FK 使用什么 ReferenceAction?它应该看起来像这样:table.ForeignKey(name: "FK_Categories_Categories_ParentId", column: x =&gt; x.ParentId, principalTable: "Categories", principalColumn: "Id", onDelete: ReferentialAction.Restrict);
  • @Omid 截图显示ParenId0(零),与null不一样,很可能是导致错误的原因。

标签: c# sql-server entity-framework-core


【解决方案1】:

在你处理输入值的地方试试这个:

if (category.ParentId == 0)
{
    category.ParentId = null;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2015-05-17
    • 1970-01-01
    • 2012-06-03
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多