EF Core Code-First Migration级联删除问题
EF Core Code-First Migration Cascade delete problem
我已经开始在项目的 后端 部分工作,目前,我正在尝试 生成数据库 使用 EF Core Code-First 但我在尝试 运行 迁移时遇到了问题(与级联删除有关)。
首先,我将在下面附上数据库的 ERD 和我创建的 类在 C# 中:
对应的分类是:
Account.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; }
}
BillingAddress.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; }
}
Customer.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; }
}
Payment.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; }
}
Rental.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; }
}
Vehicle.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.Cascade 替换为 ReferentialAction.NoAction for onDelete 在迁移中,但我不确定我是否真的应该这样做,以及从长远来看它将如何影响我的应用程序。
我究竟应该怎么做才能解决这个问题?哪个是最佳做法?
如果您正在编辑迁移,您可能需要更改实体的配置。
示例:
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
}
}
我会查看以下有关配置的文档/教程:
- Configurations
- Move Fluent API Configurations to a Separate Class in Entity Framework
- 这是 EF6,但理念相同
- EF Core Cascade Delete
在我过去完成的项目中,一些主要开发人员建议我永远不要级联删除。尽管它很方便,但您应该注意要删除的数据...EF Core 很棒,但有时它会让您默认执行一些 DBA 不会满意的行为。
我已经开始在项目的 后端 部分工作,目前,我正在尝试 生成数据库 使用 EF Core Code-First 但我在尝试 运行 迁移时遇到了问题(与级联删除有关)。
首先,我将在下面附上数据库的 ERD 和我创建的 类在 C# 中:
对应的分类是:
Account.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; }
}
BillingAddress.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; }
}
Customer.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; }
}
Payment.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; }
}
Rental.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; }
}
Vehicle.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.Cascade 替换为 ReferentialAction.NoAction for onDelete 在迁移中,但我不确定我是否真的应该这样做,以及从长远来看它将如何影响我的应用程序。
我究竟应该怎么做才能解决这个问题?哪个是最佳做法?
如果您正在编辑迁移,您可能需要更改实体的配置。
示例:
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
}
}
我会查看以下有关配置的文档/教程:
- Configurations
- Move Fluent API Configurations to a Separate Class in Entity Framework
- 这是 EF6,但理念相同
- EF Core Cascade Delete
在我过去完成的项目中,一些主要开发人员建议我永远不要级联删除。尽管它很方便,但您应该注意要删除的数据...EF Core 很棒,但有时它会让您默认执行一些 DBA 不会满意的行为。