Auto-référencement dans EF Core Erreur: l'instruction d'insertion est en conflit avec la clé étrangère même contrainte de table

Aug 18 2020

J'ai un Categorymodèle avec auto-référence et j'ai bien travaillé sur la création d'une base de données quand j'essaye d'insérer une catégorie parente (une entité sans parentId) j'obtiens l'erreur pointant vers la clé étrangère "ParentId", mais cela fonctionne bien quand j'insère un topel manuellement avec un script d'insertion dans SSMS et fonctionne très bien avec ef core lors de l'ajout d'une sous-catégorie (une entité qui a un parentId)

Modèle de catégorie

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

Migration

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

J'ai marqué "ParentId" nullable de toute façon, je pourrais encore ef core m'empêche bien que le serveur SQL fonctionne bien!

Exception interne du message d'erreur:

L'instruction INSERT était en conflit avec la contrainte FOREIGN KEY SAME TABLE "FK_Categories_Categories_ParentId". Le conflit s'est produit dans la base de données "Unknown_Db", table "dbo.Categories", colonne "Id".

Réponses

1 happykratos Aug 18 2020 at 00:38

Essayez ceci où vous gérez les valeurs d'entrée:

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