冲突发生在数据库 "X"、table "dbo.Y"、列 'ld'

The conflict occurred in database "X", table "dbo.Y", column 'ld'

我试图删除评论最多的一定数量的动物,因此我收到以下错误: SqlException:DELETE 语句与 REFERENCE 约束“FK__Comments__Animal__2EDAF651”冲突。冲突发生在数据库“PetShop”的 table“dbo.Comments”列 'AnimalId' 中。该语句已终止。 我想让它成为可能,如果我删除,那么你将转到下一行

我的显示控制器:

public async Task<IActionResult> Index()
    {
        var animal = _context.Animals.Include(c => c.Comments).OrderByDescending(c => c.Comments.Count).Take(2);
        return View(await animal.ToListAsync());

    }

我的删除控制器:

 public async Task<Animal> DeleteAnimal(int id)
    {
        var comment = await _context.Comments.FindAsync(id);
        _context.Comments.Remove(comment!);
        var animal = await _context.Animals.FindAsync(id);
        _context.Animals.Remove(animal!);
        await _context.SaveChangesAsync();
        return animal!;
    }

我的背景:

protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder.Entity<Comment>(entity =>
        {
            entity.HasOne(d => d.Animal)
                .WithMany(p => p.Comments)
                .HasForeignKey(d => d.AnimalId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK__Comments__Animal__2EDAF651");
        });

        modelBuilder.Entity<Category>(entity =>
        entity.HasData(
         new { CategoryId = 1, Name = "Dogs" },
         new { CategoryId = 2, Name = "Cats" },
         new { CategoryId = 3, Name = "Birds" },
         new { CategoryId = 4, Name = "Rabbits" },
         new { CategoryId = 5, Name = "Hamsters" }
        )
        );

        modelBuilder.Entity<Animal>(entity =>
        {
            entity.HasData(
            new { AnimalId = 1, Name = "Shoko", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-1).AddDays(-12), Description = "Friendly and loyal", CategoryId = 1, PhotoUrl = "ShokoDog.jpg" },
            new { AnimalId = 2, Name = "Bamba", BirthDate = DateTime.Now.AddYears(-2).AddMonths(-2).AddDays(-3), Description = "Furry and neutered", CategoryId = 2, PhotoUrl = "BambaCat.jpg" },
            new { AnimalId = 3, Name = "Regev", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-3).AddDays(-3), Description = "Speak", CategoryId = 3, PhotoUrl = "RegevBird.jpg" },
            new { AnimalId = 4, Name = "Humi", BirthDate = DateTime.Now.AddYears(-3).AddMonths(-4).AddDays(-7), Description = "Cute and furry", CategoryId = 4, PhotoUrl = "HumiRabbit.jpg" },
            new { AnimalId = 5, Name = "Tommy", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-7).AddDays(-9), Description = "Love to play in the facilities", CategoryId = 5, PhotoUrl = "TommyHamster.jpg" });
        });
        OnModelCreatingPartial(modelBuilder);
    }

错误消息显示您正在删除具有关联评论的 Animal。您应该执行以下操作之一:

  1. 在删除 Animal 之前删除与特定 Animal 关联的评论。
  2. 删除时检查级联的 EF 配置
  3. 更改 FK 以在删除时进行级联(这取决于您使用的是 database-first 还是 code-first 方法)

我会选择第一种方法,因为级联删除可能很危险,并且会静默删除无意中引用的数据。

您想删除父 Animal 和相关的子评论

扩展 Karlis 的建议:

  1. 你有问题中发布的模型和上下文(这有点问题,因为你告诉 EF 设置 null,但代码和 DB 不会接受 null)但你可以这样做:
    var a = context.Animals.Include(a => a.Comments).Find(id):
    context.Comments.RemoveRange(a.Comments);
    context.Animals.Remove(a);
    context.SaveChanges();

这明确删除了评论然后是动物

  1. 更改上下文以使用 .OnDelete(DeleteBehavior.ClientCascade) 然后你可以这样做:
    var a = context.Animals.Include(a => a.Comments).Find(id):
    context.Animals.Remove(a);
    context.SaveChanges();

当您明确告诉它删除动物时,这会导致 EF 隐式删除它知道的评论

  1. 更改数据库的外键以执行 ON DELETE CASCADE,并更改 .OnDelete(DeleteBehavior.Cascade) 然后您可以跳过下载评论(不包括):
    var a = context.Animals.Find(id):
    context.Animals.Remove(a);
    context.SaveChanges();

这会导致 DB 在 EF 指示删除动物时删除评论(EF 不知道它们)


从广义上讲,这些是按照“你能犯多严重的错误”从“不是很严重”到“相当多”的顺序排列