首页 > 解决方案 > EF Core Code-First Migration Cascade删除问题

问题描述

我已经开始处理项目的后端部分,目前,我正在尝试使用EF Core Code-First生成数据库,但在尝试运行迁移时遇到了问题(与级联删除)。

首先,我将在ERD下面附上DB 和我在 C# 中创建的类:

在此处输入图像描述

对应的分类有:

帐户.cs

public class Account
{
   public int Id { get; set; }
   public string Email { get; set; }
   public string ExternalAccountId { get; set; }

   public int CustomerId { get; set; }
   public Customer Customer { get; set; }
}

帐单地址.cs

public class BillingAddress
{
   public int Id { get; set; }
   public string Address { get; set; }

   public int CustomerId { get; set; }
   public Customer Customer { get; set; }

   public List<Payment> Payments { get; set; }
}

BillingDetail.cs

public class BillingDetail
{
   public int Id { get; set; }
   public int CreditCardNumber { get; set; }
   public DateTime ExpirationDate { get; set; }
   public short Cvv { get; set; }

   public int CustomerId { get; set; }
   public Customer Customer { get; set; }

   public List<Payment> Payments { get; set; }
}

客户.cs

public class Customer
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string PhoneNumber { get; set; }
   public int Cnp { get; set; }

   public Account Account { get; set; }

   public List<BillingDetail> BillingDetails { get; set; }

   public List<BillingAddress> BillingAddresses { get; set; }

   public List<Rental> Rentals { get; set; }
}

付款.cs

public class Payment
{
    public int Id { get; set; }

    public int RentalId { get; set; }
    public Rental Rental { get; set; }

    public int BillingDetailId { get; set; }
    public BillingDetail BillingDetail { get; set; }

    public int BillingAddressId { get; set; }
    public BillingAddress BillingAddress { get; set; }
}

出租.cs

public class Rental
{
   public int Id { get; set; }
   public DateTime PickupDate { get; set; }
   public DateTime DropoffDate { get; set; }

   public int CustomerId { get; set; }
   public Customer Customer { get; set; }

   public List<Payment> Payments { get; set; }

   public List<RentalVehicle> RentalVehicles { get; set; }
}

RentalVehicle.cs

public class RentalVehicle
{
   public int Id { get; set; }

   public int RentalId { get; set; }
   public Rental Rental { get; set; }

   public int VehicleId { get; set; }
   public Vehicle Vehicle { get; set; }
}

车辆.cs

public class Vehicle
{
   public int Id { get; set; }
   public string Model { get; set; }
   public string Brand { get; set; }
   public string Color { get; set; }
   public short ManufactureYear { get; set; }
   public string Vin { get; set; }
   public int Mileage { get; set; }
   public short Horsepower { get; set; }
   public string GearBox { get; set; }
   public byte EngineSize { get; set; }
   public float Price { get; set; }
   public byte NoDoors { get; set; }

   public List<RentalVehicle> RentalVehicles { get; set; }
}

我已经生成了迁移,当我尝试运行它时,我收到了如下错误:

Introducing FOREIGN KEY constraint 'FK_Payments_BillingDetails_BillingDetailId' on table 'Payments' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我已经找到了一些解决方法,可以在迁移中用 ReferentialAction.NoAction 替换ReferentialAction.Cascade用于onDelete 但我不确定我是否真的应该这样做,以及从长远来看它将如何影响我的应用程序。

我究竟应该怎么做才能解决这个问题,这是最佳实践?

标签: c#databaseentity-framework-coreef-code-first

解决方案


如果您正在编辑迁移,您可能需要更改实体的配置。

例子:

public class PaymentsConfiguration : IEntityTypeConfiguration<Payments>
    {
        public override void Configure(EntityTypeBuilder<Payments> builder)
        {
            builder.HasOne(x => x.BillingDetail).WithMany().OnDelete(DeleteBehavior.Restrict);
            builder.HasOne(x => x. BillingAddress).WithMany().OnDelete(DeleteBehavior.Restrict); //maybe you need to do this too
            builder.HasOne(x => x. Rental).WithMany().OnDelete(DeleteBehavior.Restrict); //maybe you need to do this too
        }
    }

我将查看以下有关配置的文档/教程:

在我过去做过的项目中,一些主要开发人员建议我不要级联删除。尽管它很方便,但您应该注意要删除的数据...... EF Core 很棒,但有时它会让您默认执行一些 DBA 不喜欢的行为。


推荐阅读