定义多对多关系的代码第一种方法导致关于“循环或多个级联路径”的mssql错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了定义多对多关系的代码第一种方法导致关于“循环或多个级联路径”的mssql错误相关的知识,希望对你有一定的参考价值。

我正在尝试使用Code First方法在我的数据库中创建一些表,我也需要一个多对多关系。

这是我的实体的定义:

public class User

    ...
    public virtual ICollection<UserCourse> UserCourses  get; set; 


public class Course

    ...
    public virtual ICollection<UserCourse> UserCourses  get; set; 


public class UserCourse

    public int UserId  get; set; 
    public User User  get; set; 

    public int CourseId  get; set; 
    public Course Course  get; set; 

然后我不得不告诉EF Core我希望它成为一个M-M关系:

// set many-to-many relationship between user and course

modelBuilder.Entity<UserCourse>()
    .HasKey(uc => new uc.UserId, uc.CourseId);

modelBuilder.Entity<UserCourse>()
    .HasOne(uc => uc.User)
    .WithMany(u => u.UserCourses)
    .HasForeignKey(uc => uc.UserId);

modelBuilder.Entity<UserCourse>()
    .HasOne(uc => uc.Course)
    .WithMany(c => c.UserCourses)
    .HasForeignKey(uc => uc.CourseId);

我没有为我的实体指定DeleteBehavior,所以SQL Server给了我错误:

在'UsersCourses'表上引入FOREIGN KEY约束'FK_UsersCourses_Users_UserId'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

所以我找了一些解决方案,发现我必须指定DeleteBehaviour。我这样做是这样的:

// set ondelete to be restrict

modelBuilder.Entity<UserCourse>()
     .HasOne(uc => uc.User)
     .WithMany(u => u.UserCourses)
     .Metadata.DeleteBehavior = DeleteBehavior.Restrict;

modelBuilder.Entity<UserCourse>()
     .HasOne(uc => uc.Course)
     .WithMany(c => c.UserCourses)
     .Metadata.DeleteBehavior = DeleteBehavior.Restrict;

虽然SQL Server要求我将OnDelete更改为NO ACTION,但DeleteBehavior枚举中没有NO ACTION。相反,它是在ReferentialAction枚举中,这是一个迁移的枚举,所以我不能手动触摸它(我的意思是它似乎是一个糟糕的设计决定)。互联网上的人说Restrict正是我在这里寻找的。好。那么问题应该解决了,对吧?不幸的是,绝对没有。

SQL Server仍然给我同样的错误:

在'UsersCourses'表上引入FOREIGN KEY约束'FK_UsersCourses_Users_UserId'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

我根本不知道该怎么做。我尝试了几乎所有的东西,虽然我不是那种在EF核心代码优先方法方面经验丰富的人。

我的问题很简单:我该如何解决这个问题?

答案

删除所有迁移并初始化新的(第一次)迁移帮助了我。

为此,请执行以下步骤:

  1. 从项目中删除迁移文件夹。
  2. 从DB中删除__EFMigrationsHistory表(drop table __EFMigrationsHistory)
  3. 在Package Manager控制台中键入以下内容:“Add-Migration Initial”
  4. 在包管理器控制台中键入以下内容:“update-database”

以上是关于定义多对多关系的代码第一种方法导致关于“循环或多个级联路径”的mssql错误的主要内容,如果未能解决你的问题,请参考以下文章

OnDelete(DeleteBehavior.Cascade) 可能会导致循环或多个级联路径

关于多对多关系的问题:完全迭代

关于JPA一对一,一对多(多对一),多对多的详解

hibernate 表关系映射详解之多对多

关于symfony的多对多关联关系的字段更新

创建多对多表关系的三种方式