Reputation: 1020
I've started to work on the back-end part for a project and currently, I'm trying to generate the DB using EF Core Code-First but I've encountered an issue when I tried to run the migration (is related to cascade delete).
First of all, I'll attach below the ERD for the DB and the classes I've created in C#:
And the corresponding classed are:
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; }
}
I've generated the migration and when I try to run it, I'm getting errors like this:
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.
I've found some fixed to replace ReferentialAction.Cascade with ReferentialAction.NoAction for onDelete in migration, but I'm not sure if I really should do this and how it will impact this thing my app in the long term.
What exactly should I do to fix this and which is the best practice?
Upvotes: 2
Views: 1044
Reputation: 384
If you are editing a migration, chances are you need to make a change in your configuration of your entity.
Example:
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
}
}
I would review the following documentation / tutorials regarding configurations:
In projects I've done in the past and some lead developers have suggested to me to never cascade deletes. As convenient as it is, you should be mindful as to what data you are deleting... EF Core is great, but sometimes it defaults you to some behaviors a DBA will not be happy about.
Upvotes: 3