在我的常规.NET Framework应用程序中,我使用的是EF 6.x并且还使用了一些继承,特别是:
PurchaseOrder.cs 和 SaleOrder.cs 都继承自 Order.cs
在我继承自OnModelCreating()
的上下文类的IdentityDbContext
中,我正在做:
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
这曾经有用,但现在我正在将我的应用程序移动到.NET Core 2.0,而我正在使用EF Core。什么在EF Core中实现了同样的目的?因为我现在收到错误:
System.Data.SqlClient.SqlException(0x80131904):介绍FOREIGN KEY约束&#39; FK_Order_Business_CustomerId&#39;在桌子上&#39;订购&#39;可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
更新
这是艾哈迈尔回答后的代码。在我的上下文课中,我有:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.HasDefaultSchema("PD");
builder.Entity<Customer>()
.HasMany(c => c.SaleOrders)
.WithOne(e => e.Customer)
.OnDelete(DeleteBehavior.SetNull);
builder.Entity<Supplier>()
.HasMany(po => po.PurchaseOrders)
.WithOne(e => e.Supplier)
.OnDelete(DeleteBehavior.SetNull);
builder.Entity<PurchaseOrder>()
.HasMany(li => li.LineItems)
.WithOne(po => po.PurchaseOrder)
.OnDelete(DeleteBehavior.SetNull);
builder.Entity<SaleOrder>()
.HasMany(li => li.LineItems)
.WithOne(po => po.SaleOrder)
.OnDelete(DeleteBehavior.SetNull);
}
就实体而言,它们是:
public abstract class Business : IEntity
{
protected Business()
{
CreatedOn = DateTime.UtcNow;
}
public int Id { get; set; }
public string Name { get; set; }
public string TaxNumber { get; set; }
public string Description { get; set; }
public string Phone { get; set; }
public string Website { get; set; }
public string Email { get; set; }
public bool IsDeleted { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
public ICollection<Address> Addresses { get; set; } = new List<Address>();
public ICollection<Contact> Contacts { get; set; } = new List<Contact>();
}
[Table("Customers")]
public class Customer : Business
{
public decimal AllowedCredit { get; set; }
public decimal CreditUsed { get; set; }
public int NumberOfDaysAllowedToBeOnMaxedOutCredit { get; set; }
public ICollection<SaleOrder> SaleOrders { get; set; }
}
[Table("Suppliers")]
public class Supplier : Business
{
public ICollection<PurchaseOrder> PurchaseOrders { get; set; }
}
public abstract class Order : IEntity
{
protected Order()
{
Date = DateTime.UtcNow;
CreatedOn = DateTime.UtcNow;
}
public int Id { get; set; }
public DateTime Date { get; set; }
public decimal ShippingCost { get; set; }
public Currency ShippingCurrency { get; set; }
public decimal ShippingConversionRate { get; set; }
public bool IsDeleted { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
public ICollection<Invoice> Invoices { get; set; }
public ICollection<Note> Notes { get; set; }
}
[Table("PurchaseOrders")]
public class PurchaseOrder : Order
{
public int SupplierOrderNumber { get; set; }
public PurchaseOrderStatus Status { get; set; }
public decimal Vat { get; set; }
public decimal ImportDuty { get; set; }
public int SupplierId { get; set; }
public Supplier Supplier { get; set; }
public ICollection<PurchaseOrderLineItem> LineItems { get; set; }
}
[Table("SaleOrders")]
public class SaleOrder : Order
{
public decimal AmountToBePaidOnCredit { get; set; }
public SaleOrderStatus Status { get; set; }
public ICollection<SaleOrderLineItem> LineItems { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
}
所以在做了Ahmar的建议之后,我update-database
时仍然会遇到同样的错误。
答案 0 :(得分:1)
您需要在.Net Core EF中的每个实体上配置级联删除行为。
实体框架Core Fluent API OnDelete
方法用于指定在删除主体时应在关系中的依赖实体上发生的操作。
OnDelete方法将DeleteBehavior
枚举作为参数:
示例:
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employees { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public int? CompanyId { get; set; }
public Company Company { get; set; }
}
protected override void OnModelCreating(Modelbuilder modelBuilder)
{
modelBuilder.Entity<Company>()
.HasMany(c => c.Employees)
.WithOne(e => e.Company).
.OnDelete(DeleteBehavior.SetNull);
}
删除公司时,会将Employee表中的CompanyId属性设置为null。
在Configuring One To Many Relationships
了解更多详情 PS。请确保您的所有引用属性都应为null,因此,EF Core可以在删除时将它们设置为null。比如示例中的CompanyId
。