简体   繁体   English

Conventions.Remove <OneToManyCascadeDeleteConvention> ()在EF Core中?

[英]Conventions.Remove<OneToManyCascadeDeleteConvention>() in EF Core?

In my regular .NET Framework application, I was using EF 6.x and was also using some Inheritance, specifically: 在我的常规.NET Framework应用程序中,我使用的是EF 6.x,还使用了某些继承,特别是:

PurchaseOrder.cs and SaleOrder.cs both inherit from Order.cs PurchaseOrder.csSaleOrder.cs都继承自Order.cs

And in the OnModelCreating() on my context class inheriting from IdentityDbContext , I was doing: 在从IdentityDbContext继承的上下文类的OnModelCreating() ,我正在做:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

This used to work, but now I am moving my application to .NET Core 2.0 and I am using EF Core. 这曾经可以工作,但是现在我将应用程序移至.NET Core 2.0,并且正在使用EF Core。 What achieves the same thing in EF Core? 在EF Core中,什么可以实现相同的目的? Because right now I am getting the error: 因为现在我得到了错误:

System.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN KEY constraint 'FK_Order_Business_CustomerId' on table 'Order' may cause cycles or multiple cascade paths. System.Data.SqlClient.SqlException(0x80131904):在表“ Order”上引入FOREIGN KEY约束“ FK_Order_Business_CustomerId”可能会导致循环或多个级联路径。 Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

UPDATE UPDATE

Here's the code after Ahmar's answer. 这是Ahmar回答后的代码。 In my context class, I have: 在上下文类中,我有:

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);
}

And as far the Entities, they are: 就实体而言,它们是:

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; }
}

So after doing what Ahmar suggested, I still get the same error when I do update-database . 因此,在执行了Ahmar的建议之后,当我执行update-database时,仍然出现相同的错误。

You need to configure cascade delete behavior on each entity in .Net Core EF. 您需要在.Net Core EF中的每个实体上配置级联删除行为。

The Entity Framework Core Fluent API OnDelete method is used to specify the action which should take place on a dependent entity in a relationship when the principal is deleted. 实体框架核心Fluent API OnDelete方法用于指定删除主体时应在关系中的从属实体上执行的操作。

The OnDelete method takes a DeleteBehavior enum as a parameter: OnDelete方法将DeleteBehavior枚举作为参数:

  • Cascade - dependents should be deleted 级联-依赖项应删除
  • Restrict - dependents are unaffected 限制-家属不受影响
  • SetNull - the foreign key values in dependent rows should update to NULL SetNull-相关行中的外键值应更新为NULL

Example: 例:

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);
}

When deleting the Company, it will set CompanyId property in Employee table to null. 删除公司时,会将Employee表中的CompanyId属性设置为null。

Get more detail at Configuring One To Many Relationships 配置一对多关系中获得更多详细信息

PS. PS。 Please make sure your all referencing properties should be null able so, EF Core can set them null on delete. 请确保您所有的引用属性都应为null,以便EF Core可以在删除时将它们设置为null。 like CompanyId in about example. 类似于CompanyId中的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM