【问题标题】:Entity Framework Core 5 - Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade pathsEntity Framework Core 5 - 在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径
【发布时间】:2021-10-06 13:52:20
【问题描述】:

我正在尝试实现实体框架核心 5 我也是新手。以下是我正在尝试实现的三个模型。

在发布新问题之前,我检查了以下答案,但无法理解卡片示例。也许下面列出的我的问题会帮助今天像我这样的其他人更好地理解它。

  1. Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?
  2. Foreign key constraint may cause cycles or multiple cascade paths?

我的模型如下:

[Table("Clinics")]
public class Clinic
{
    public int ClinicID { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public string Address { get; set; }

    public List<Doctor> DoctorsAvailable { get; set; } = new List<Doctor>();
}


[Table("Doctors")]
public class Doctor
{
    public int ID { get; set; }

    public string Name { get; set; }

    public DoctorsSpecilization Specilization { get; set; }

    public string PhoneNumber { get; set; }

    public string Email { get; set; }

    public List<Clinic> ClinicsAvailableAt { get; set; } = new List<Clinic>();
}

 [Table("Patients")]
public class Patient
{
    public int PatientID { get; set; }

    public string Name { get; set; }

    public string Address { get; set; }

    public string PhoneNumber { get; set; }

    public string Email { get; set; }

    public int DoctorID { get; set; }

    public Doctor Doctor { get; set; }
}


[Table("Consultations")]
public class Consultation
{
    public int ID { get; set; }

    public int ClinicID { get; set; }

    public int DoctorID { get; set; }

    public int PatientID { get; set; }

    public Clinic Clinic { get; set; }

    [ForeignKey("DoctorID")]
    public Doctor Doctor { get; set; }

    [ForeignKey("PatientID")]
    public Patient Patient { get; set; }

    public DateTime StartTime { get; set; }

    public DateTime EndTime { get; set; }

}

问题是咨询模型中医生和患者的导航属性。当我尝试“更新数据库”时它失败了

在表“Consultations”上引入 FOREIGN KEY 约束“FK_Consultations_Patients_PatientID”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。

但是,如果导航属性被删除,它可以正常工作。你可能会问我为什么需要这些导航属性。这是为了在视图上显示相关信息。

非常感谢您对解释或评论该概念的任何帮助。

谢谢。

【问题讨论】:

  • 如果你也显示 Patient 类会很好
  • 所示模型中没有可见的循环。请 (1) 提供第三个相关实体 (Patient) (2) 您是否使用 EF Core 5,因此在 ClinicDoctor 之间存在隐式多对多链接表?
  • @Serge 我已将其添加到代码中。
  • @IvanStoev 1:添加到代码中。 2:是的

标签: asp.net-mvc asp.net-core entity-framework-core


【解决方案1】:

这是所示模型中的级联删除路径

  1. 诊所 -> 咨询
  2. 医生->咨询
  3. 患者 -> 咨询
  4. 医生 -> 病人 -> 咨询

问题(多级联路径)是最后两个。如您所见,删除Doctor时,可以直接删除链接的Consultation记录,也可以查看链接的Patient记录。由于这种可能性,一些数据库(主要是 SqlServer)拒绝级联删除选项,并要求您为形成循环的至少一个关系关闭它并手动或通过触发器处理删除。

所以通常情况下,当这种循环存在时,你应该这样做。

但这里的模型似乎有问题。要么Patient不应该链接到单个Doctor,而是通过链接表和删除Patient.Doctor导航属性(因此关联的FK关系)来链接多个,从而自然打破多个级联路径,即删除Doctor删除只是链接到诊所和病人,而不是诊所和病人本身。

或者,如果您想保持Patient 到单个Doctor 关系,那么Consultation.Doctor(以及关联的Consultation.DoctorId FK 和关系)是多余的 - 可以通过咨询获得咨询的医生。患者。医生)。所以删除它,这也将解决多级联路径问题,因为将不再有Doctor -&gt; Consultation 级联删除链接。

为清楚起见,建议的第一个选项需要更改以下模型:


[Table("Clinics")]
public class Clinic // Unchanged
{
    public int ClinicID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Address { get; set; }
    public List<Doctor> DoctorsAvailable { get; set; } = new List<Doctor>();
}

[Table("Doctors")]
public class Doctor
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public List<Clinic> ClinicsAvailableAt { get; set; } = new List<Clinic>();
    public ICollection<Patient> Patients { get; set; } // <-- added
}

[Table("Patients")]
public class Patient
{
    public int PatientID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    //public int DoctorID { get; set; } <-- removed
    //public Doctor Doctor { get; set; } <-- removed
    public ICollection<Doctor> Doctors { get; set; } // <-- added
}


[Table("Consultations")]
public class Consultation // Unchanged
{
    public int ID { get; set; }
    public int ClinicID { get; set; }
    public int DoctorID { get; set; }
    public int PatientID { get; set; }
    public Clinic Clinic { get; set; }
    [ForeignKey("DoctorID")]
    public Doctor Doctor { get; set; }
    [ForeignKey("PatientID")]
    public Patient Patient { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

和选项 2:


[Table("Clinics")]
public class Clinic // Unchanged
{
    public int ClinicID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Address { get; set; }
    public List<Doctor> DoctorsAvailable { get; set; } = new List<Doctor>();
}

[Table("Doctors")]
public class Doctor // Unchanged
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public List<Clinic> ClinicsAvailableAt { get; set; } = new List<Clinic>();
}

[Table("Patients")]
public class Patient // Unchanged
{
    public int PatientID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public int DoctorID { get; set; }
    public Doctor Doctor { get; set; }
}


[Table("Consultations")]
public class Consultation
{
    public int ID { get; set; }
    public int ClinicID { get; set; }
    //public int DoctorID { get; set; } <-- removed
    public int PatientID { get; set; }
    public Clinic Clinic { get; set; }
    //[ForeignKey("DoctorID")]
    //public Doctor Doctor { get; set; } <-- removed
    [ForeignKey("PatientID")]
    public Patient Patient { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

【讨论】:

  • 谢谢伊万。在我按照您的建议删除了咨询模型中的医生导航属性和 DoctorID 属性之后。它现在显示错误,因为在表“咨询”上引入外键约束“FK_Consultations_Patients_PatientID”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION。另外,我认为客户是您的回答中的错字,您实际上是指咨询模型?
  • 按照您提到的方式完成了这两件事。它失败。在表“Consultations”上引入 FOREIGN KEY 约束“FK_Consultations_Patients_PatientID”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。
  • 尝试从 Consultation 中删除 Doctor 属性,生成迁移,更新数据库,并且它在没有问题的情况下工作。您还有其他未显示的内容吗?
  • 并非如此。同样在这里。删除医生属性后生成迁移,并将 Patient 中的单个医生属性作为医生列表。更新数据库失败。
  • 我唯一做的附加模组是评论public DoctorsSpecilization Specilization { get; set; },因为不知道它是什么。
猜你喜欢
  • 2021-08-24
  • 2017-06-04
  • 2011-05-08
  • 2013-10-22
  • 2020-12-20
  • 2021-05-30
相关资源
最近更新 更多