定义多对多关系的代码优先方法导致有关“循环或多个级联路径”的mssql错误

马克·帕夫洛维奇

我试图使用“代码优先”方法在数据库中创建一些表,那里也需要“多对多”关系。

这是我实体的定义:

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我希望它成为MM关系:

// 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枚举中,该枚举是迁移的枚举,因此我无法手动进行操作(我的意思是这似乎是一个错误的设计决策)。互联网上的人们说,限制正是我在这里寻找的东西。好。好吧,那问题应该解决了吧?不幸的是,绝对不是。

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

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

我根本不知道该怎么办。我几乎尝试了所有方法,尽管我对EF Core Code-first方法没有经验。

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

马克·帕夫洛维奇

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

为此,请执行以下步骤:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章