约束可能导致循环或多个级联路径

kse*_*een 0 sql-server entity-framework foreign-keys ef-migrations

它是这样的:

public class ApplicationUser : IdentityUser
{
    // omitted for the sake of brevity...

    public string LastName { get; set; }
    public string FirstName { get; set; }

    public string Email { get; set; }
}

public class Invoice
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Index(IsUnique = true)]
    [Required]
    public int No { get; set; }

    [Required]
    public DateTime Created { get; set; }

    [Required]
    public string ManagerId { get; set; }
    public virtual ApplicationUser Manager { get; set; }

    public virtual ICollection<InvoicePayment> Payments { get; set; }
}

public class InvoicePayment
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public int InvoiceId { get; set; }
    public virtual Invoice Invoice { get; set; }

    [Required]
    public DateTime Created { get; set; }

    [Required]
    public decimal Total { get; set; }

    public string Comment { get; set; }

    public virtual ICollection<InvoicePaymentParticipant> Participants { get; set; }
}

public class InvoicePaymentParticipant
{
    [Key]
    public Guid Id { get; set; }

    [Required]
    public Guid InvoicePaymentId { get; set; }
    public virtual InvoicePayment InvoicePayment { get; set; }

    [Required]
    public string ManagerId { get; set; }
    public virtual ApplicationUser Manager { get; set; }

    [Required]
    public decimal Part { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试Update-Database大喊:

在表'InvoicePaymentParticipants'上引入FOREIGN KEY约束'relationship_name'可能会导致>循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他> FOREIGN KEY约束。无法创建约束或索引。请参阅先前的错误。

我误解了多个级联路径的概念。

我不明白问题出在哪里,因为如果我们想删除经理,我们也希望他们的付款参与记录以及他们创建的任何发票都被删除。

您如何在给定的方案中解决此问题?

Hoo*_*ini 5

当您在必需(或不可为空)属性上创建外键关系时,默认情况下会启用级联删除,请参阅EF必需关系

这里的问题是您有2个InvoicePaymentParticipantApplicationUser表的级联删除路径:

Path1: InvoicePaymentParticipant -> InvoicePayment -> Invoice -> ApplicationUser

Path2: InvoicePaymentParticipant -> ApplicationUser
Run Code Online (Sandbox Code Playgroud)

这意味着,当您删除用户时,应删除以下记录:

路径1下的删除:

  1. 用户被删除,删除他的发票
  2. 发票被删除,删除相应的发票付款
  3. 发票付款被删除,删除相应的发票付款参与者

路径2下的删除:

  1. 用户被删除,删除他的发票付款参与者

Sql Server中不允许这样做。请参阅此页面以获取更多信息。

为了解决这个问题,你可以重新考虑你的表结构和删除外键路径之一InvoicePaymentParticipant,以ApplicationUser...

另一种方法是更改​​外键的级联删除行为,您可以删除[Required]其中一个属性的ManagerId属性,并且由于stringnullable类型,EF会在删除时将设置为null

您还可以更改EF默认行为并关闭级联删除

  • 这是一个很好的建议,在我的应用程序中,我通常会禁用级联删除约定,并手动指定要允许级联方案的关系。考虑这一点,如果用户X支付了发票,而用户X被删除了,您是否真的希望发票也被删除?如果您允许删除财务记录,则很难平衡您的账目并维护财务历史记录。 (2认同)