引入FOREIGN KEY可能会导致循环或多个级联路径

时间:2016-04-02 08:54:19

标签: entity-framework foreign-keys foreign-key-relationship cascade

我正在使用实体框架和代码优先方法。

在我的onModelCreating中,我使用键和关系创建表格(我使用的是Fluent API方法,而不是数据注释)。

但是当我尝试使用Update-Database命令生成模型时,我收到以下错误

  

介绍FOREIGN KEY约束' FK_customers.invoices_customers.billingCenters_billingCenterId'在桌面'发票'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。无法创建约束。查看以前的错误。

我几乎可以肯定我没有周期...如果我有级联路径,我就不会有问题。这就是我想要的东西!

按照我正在创建的模型:

modelBuilder.Entity<Customer>()
    .ToTable("customers", schemaName)
    .HasKey(c => new { c.Code });

modelBuilder.Entity<BillingCenter>()
    .ToTable("billingCenters", schemaName)
    .HasKey(bc => new { bc.Id });

//1 Customer -> N BillingCenters
modelBuilder.Entity<BillingCenter>()
    .HasRequired(bc => bc.Customer)
    .WithMany(c => c.BillingCenters)
    .HasForeignKey(bc => bc.CustomerId);

modelBuilder.Entity<Invoice>()
    .ToTable("invoices", schemaName)
    .HasKey(i => new { i.Id });

//Here the code gives me problems
//1 BillingCenter -> N Invoices
modelBuilder.Entity<Invoice>()
    .HasRequired(i => i.BillingCenter)
    .WithMany(bc => bc.Invoices)
    .HasForeignKey(i => i.BillingCenterId);

modelBuilder.Entity<Payment>()
    .ToTable("payments", schemaName)
    .HasKey(ep => new { ep.Id })
    .Property(ep => ep.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

//1 Customer -> N Payments
modelBuilder.Entity<Payment>()
    .HasRequired(ep => ep.customer)
    .WithMany(c => c.Payments)
    .HasForeignKey(ep => ep.customerCode);

//1 Invoice -> N Payments (Failed, Ok, ...)
modelBuilder.Entity<Payment>()
    .HasRequired(p => p.Invoice)
    .WithMany(i => i.Payments)
    .HasForeignKey(p => p.InvoiceId);

如果我删除此代码,似乎一切正常

modelBuilder.Entity<Invoice>()
    .HasRequired(i => i.BillingCenter)
    .WithMany(bc => bc.Invoices)
    .HasForeignKey(i => i.BillingCenterId);

生成以下数据库:

enter image description here

我说SEEMS可行,因为如果我看到billingCentersinvoices之间的关系delete ruleno action

我该如何解决这个问题?

提前谢谢

1 个答案:

答案 0 :(得分:2)

  

我几乎可以肯定我没有周期

您的确有一个从customerspayments的周期。如果您删除customer,则payment可以通过customers->paymentscustomers->billingCenters->invoices->payments删除,因此可以删除。

  

如果我有级联路径,我就不会有问题。这就是我想要的!

我确信这正是我们想要的。事实上,一些数据库(肯定是Oracle)对多个级联路径没有任何问题。不幸的是SqlServer不支持它们,所以EF设计者决定不支持这样的配置。

  

我说SEEMS可行,因为如果我看到billingCenters和发票之间的关系,则删除规则不起作用。

这是因为您的迁移失败并已回滚。它确实试图设置删除级联。

  

我该如何解决这个问题?

你应该打破这个循环。您可以通过关闭至少一个关系WillCascadeOnDelete(false)customers->payments的级联删除(通过在相应的关系配置中包含customers->billingCenters)来实现此目的。

这样做会“解决”这个问题。我的意思是你将能够成功运行迁移。但请注意,您可能遇到维护问题 - 根据数据库处理FK约束的方式,可能无法简单地删除customer并且需要手动删除相关记录(payments或{{1} })删除之前。