使用 Fluent API 避免在 EF Core 2.2 中使用 n 对 m 关系和父级进行循环级联

Avoiding cyclic cascading with n-to-m relations and a parent in EF Core 2.2 with Fluent API

按照1-to-m in combination with n-to-m的配置指南,我设置了一个学校的系统,其中包含多个学生课程 实例。每个 Student 实例可能包含一个 link 到某个 Course 实例(反之亦然)。一个 Student 实例可以包含多个这样的 link(反之亦然)。

对于那些指南,这在单独使用时有效。但是当组合它们时,我在更新数据库时收到以下错误消息,尽管这样的迁移是正确生成的。

Introducing FOREIGN KEY constraint 'FK_Student_Course_Students_StudentId' on table 'Student_Course' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.

一段时间后,我意识到问题的发生是由于我的学校级联删除学生和课程。反过来,它们与它们之间的 n-to-m 关系有级联。这是一个错误,因为一旦删除,就无法重新删除。

复杂的是,我可能只删除一门课程(然后想从中级联),但我也可能只删除一个学生(并想从中级联)。

所以我需要涵盖以下情况。

  1. 学校已删除 -> 每个学生已删除,每个课程已删除,每个学生课程已删除
  2. 学生已删除 -> 学生课程已删除
  3. 课程已删除 -> student-course-ralation 已删除

我应该如何重新配置​​我的模型构建器以只导致一个删除分支?

当前配置是这样设置的

builder.Entity<Student_Course>().HasKey(sc => new { sc.StudentId, sc.CourseId });
builder.Entity<School>().HasMany(e => e.Courses)
  .WithOne(e => e.School).HasForeignKey(e => e.SchooldId);
builder.Entity<School>().HasMany(e => e.Students)
  .WithOne(e => e.School).HasForeignKey(e => e.SchooldId);

模型看起来像这样。

public class School
{
  public Guid Id { get; set; }
  public virtual IList<Student> Students { get; set; }
  public virtual IList<Course> Courses { get; set; }
}

public class Student
{
  public Guid Id { get; set; }
  public virtual IList<Student_Course> Student_Course { get; set; }
  public Guid SchooldId { get; set; }
  public virtual School School { get; set; }
}

public class Course
{
  public Guid Id { get; set; }
  public virtual IList<Student_Course> StudentCourses { get; set; }
  public Guid SchooldId { get; set; }
  public virtual School School { get; set; }
}

public class Student_Course
{
  public Guid StudentId { get; set; }
  public virtual Student Student { get; set; }
  public Guid CourseId { get; set; }
  public virtual Course Course { get; set; }
}

显然,这听起来很疯狂,但无法完成。

来源:@gertarnold 提供的“...臭名昭著的 SQL 服务器限制...”。

建议的处理方法是手动引入业务逻辑来显式处理。