การอ้างอิงตัวเองในข้อผิดพลาดหลักของ EF: คำสั่งแทรกขัดแย้งกับข้อ จำกัด ของตารางคีย์นอกเดียวกัน

Aug 18 2020

ฉันมีCategoryโมเดลที่มีการอ้างอิงตัวเองและทำงานได้ดีในการสร้างฐานข้อมูล แต่เมื่อฉันพยายามแทรกหมวดหมู่หลัก (เอนทิตีที่ไม่มี parentId) ฉันได้รับข้อผิดพลาดที่ชี้ไปที่ "ParentId" ของคีย์ต่างประเทศ แต่มันทำงานได้ดีเมื่อฉันแทรก topel ด้วยตนเองพร้อมแทรกสคริปต์ใน SSMS และทำงานได้ดีกับ ef core เมื่อเพิ่มประเภทย่อย (เอนทิตีที่มี parentId)

หมวดหมู่รุ่น

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; }
}

DBContext

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" เป็นโมฆะอย่างไรก็ตามฉันสามารถทำได้ แต่ ef core กำลังป้องกันฉันแม้ว่า SQL Server จะใช้ได้ดีก็ตาม!

ข้อผิดพลาดภายในข้อยกเว้น:

คำสั่ง INSERT ขัดแย้งกับข้อ จำกัด ของ FOREIGN KEY SAME TABLE "FK_Categories_Categories_ParentId" ความขัดแย้งเกิดขึ้นในฐานข้อมูล "Unknown_Db", ตาราง "dbo.Categories", คอลัมน์ "Id"

คำตอบ

1 happykratos Aug 18 2020 at 00:38

ลองใช้สิ่งนี้ที่คุณจัดการกับค่าอินพุต:

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