删除 table 中的列表会引发 SQL 错误

Deleting a listing in table throws a SQL error

我有一个模型机场的 .NetCore Entity Framework 项目。

当我尝试删除列表中的机场时,我在尝试删除航空公司时遇到以下错误,我正在尝试找出原因:

Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_airlinePilots_airline". The conflict occurred in database "FrankAirportTeam", table "dbo.airlinePilots", column 'airlineId'.

删除操作只是一个API方法:

    [HttpDelete("{id}")]
    public async Task<ActionResult<Airline>> DeleteAirline(long id)
    {
        var airline = await _context.Airline.FindAsync(id);
        if (airline == null)
        {
            return NotFound();
        }

        _context.Airline.Remove(airline);
        await _context.SaveChangesAsync();

        return airline;
    }

我的航空公司模型如下:

public partial class Airline
{
    public Airline()
    {
        AirlinePilots = new HashSet<AirlinePilots>();
    }

    public long Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public long CityId { get; set; }

    public virtual City City { get; set; }
    public virtual ICollection<AirlinePilots> AirlinePilots { get; set; }
}

和航空公司飞行员

    public partial class AirlinePilots
{
    public long PilotId { get; set; }
    public long AirlineId { get; set; }

    public virtual Airline Airline { get; set; }
    public virtual Pilot Pilot { get; set; }
}

航空公司的数据库上下文 class 看起来像这样:

modelBuilder.Entity<Airline>(entity =>
        {
            entity.ToTable("airline");

            entity.HasIndex(e => e.Id)
                .HasName("IX_airline");

            entity.Property(e => e.Id)
                .HasColumnName("id");

            entity.Property(e => e.Description)
                .IsRequired()
                .HasColumnName("description");

            entity.Property(e => e.CityId).HasColumnName("cityId");

            entity.Property(e => e.Title)
                .IsRequired()
                .HasColumnName("title")
                .HasMaxLength(255);

            entity.HasOne(d => d.City)
                .WithMany(p => p.Airline)
                .HasForeignKey(d => d.CityId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_airline_city");
        });

并且在 AirlinePilots [更新了新的删除方法]:

        modelBuilder.Entity<AirlinePilots>(entity =>
        {
            entity.HasKey(e => new { e.PilotId, e.AirlineId });

            entity.ToTable("airlinePilots");

            entity.Property(e => e.PilotId).HasColumnName("pilotId");

            entity.Property(e => e.AirlineId).HasColumnName("airlineId");

            entity.HasOne(d => d.Airline)
                .WithMany(p => p.AirlinePilots)
                .HasForeignKey(d => d.AirlineId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_airlinePilots_airline");

            entity.HasOne(d => d.Pilot)
                .WithMany(p => p.AirlinePilots)
                .HasForeignKey(d => d.PilotId)
                .OnDelete(DeleteBehavior.Cascade)
                .HasConstraintName("FK_airlinePilots_pilot");
        });

AirlinePilots 只是一个查找 table,它为每个 PilotId 存储一个 AirlineId。一家航空公司可以有很多飞行员。它有一个用于 AirlineId 的外键和一个用于 PilotId 的外键。

在我的数据库中,航空公司没有 AirlinePilots 的外键。但是,AirlinePilots table 确实有航空公司的外键。

因此,API 中的 DELETE 操作需要删除 AirlinePilots table.

中包含航空公司 ID 的任何关联行。

实际上我真的很害怕更改任何内容,因为我不想它意外删除 AirlinePilots 中的所有内容 table。

有什么我可以添加到我的上下文中的东西 class 来完成这项工作吗?

谢谢! :)

AirlineId 在 AirlinePilots 上不是可为空的外键,因此您不能使用 ClientSetNull,因为它会引发 SaveChanges,您需要的是使用 Cascade[=16= 实现的级联删除行为] 航空公司 fk 映射选项。:

.OnDelete(DeleteBehavior.Cascade) 

顺便说一句,从你的映射我知道你也从 Pilot 实体控制这个集合,通常这是一个设计缺陷,可能会给你带来麻烦,你可能会在内存中加载相同的项目两次指向同一数据库行,可能会出现并发问题。如果您需要显示来自 Pilot 的航空公司,请改用 return 只读实体的查询。