我正在尝试使用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核心代码优先方法方面经验丰富的人。
我的问题很简单:我该如何解决这个问题?
删除所有迁移并初始化新的(第一次)迁移帮助了我。
为此,请执行以下步骤: