C# 如何在EF 5中表达与单亲表的多对多关系
我有一个类似的系,可以有很多课程和学生。学生可以链接到许多课程,课程可以有许多学生注册到它。我还希望将学生和课程链接到一个系 我如何在EF/Fluent API中表达这一点,我已经试过了C# 如何在EF 5中表达与单亲表的多对多关系,c#,entity-framework,C#,Entity Framework,我有一个类似的系,可以有很多课程和学生。学生可以链接到许多课程,课程可以有许多学生注册到它。我还希望将学生和课程链接到一个系 我如何在EF/Fluent API中表达这一点,我已经试过了 modelBuilder.Entity<Student>().HasRequired(s => s.Department); modelBuilder.Entity<Course>().HasRequired(u => u.Department
modelBuilder.Entity<Student>().HasRequired(s => s.Department);
modelBuilder.Entity<Course>().HasRequired(u => u.Department);
modelBuilder.Entity<Course>()
.HasMany(s => s.Students)
.WithOptional()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Course>()
.HasMany(u => u.Students)
.WithMany(s => s.Courses);
modelBuilder.Entity<Student>()
.HasMany(s => s.Courses)
.WithOptional()
.WillCascadeOnDelete(false);
有什么提示/帮助吗
更新:学生班看起来像这样
public class Student
{
[Key]
public string Id { get; set; }
[Required]
public string SiteName { get; set; }
public virtual Department Department { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
公共班级学生
{
[关键]
公共字符串Id{get;set;}
[必需]
公共字符串SiteName{get;set;}
公共虚拟部门部门{get;set;}
公共虚拟ICollection课程{get;set;}
}
课程包括:
public class Course
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public virtual Department Department { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
公共课
{
[关键]
公共字符串Id{get;set;}
[必需]
公共字符串名称{get;set;}
公共虚拟部门部门{get;set;}
公共虚拟ICollection学生{get;set;}
}
这是因为为了进行类似的多对多操作,您需要在表之间创建一个链接表,您可以称之为学生课程
。然后您的学生
和课程
类将有一个类型为学生课程
的集合。下面是创建类的方法(使用数据注释):
此外,如果您仍然希望能够获取课程中的所有学生(或学生正在学习的所有课程),则可以使用公共属性的NotMapped
属性轻松获取,如下所示:
对于您的学生
班级:
[NotMapped]
public List<Course> Courses {
get { return StudentCourses.Select(sc => sc.Course); }
}
[NotMapped]
public List<Student> Students {
get { return StudentCourses.Select(sc => sc.Student); }
}
从.Entity()
开始,将所需的导航属性配置到部门
,然后指定.WillCascadeOnDelete(false)
:
modelBuilder.Entity<Department>()
.HasMany( d => d.Students )
.WithRequired()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Department>()
.HasMany( d => d.Courses )
.WithRequired()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Course>()
.HasMany(u => u.Students)
.WithMany(s => s.Courses);
modelBuilder.Entity()
.有很多(d=>d.学生)
.WithRequired()
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.有许多(d=>d.课程)
.WithRequired()
.WillCascadeOnDelete(假);
modelBuilder.Entity()
.HasMany(u=>u.Students)
.有许多(s=>s.课程);
不需要,配置.HasMany(…)。WithMany(…)
将自动生成关系表,同时保留预期的学生课程和课程。学生导航属性这是否意味着我必须加载三个实体而不是两个?(包括学生课程)?如果你这样做,那么你会的。不过,生成的SQL将保持不变,因为在任何情况下都需要生成第三个表来跟踪关系。这没有帮助,我在表“CourseStudents”上引入外键约束“FK_dbo.CourseStudents_dbo.Students_Student_Id”时出现了此错误,可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。是的,抱歉,删除With可选,但移动将级联删除到现有的。有许多(…)。With许多(…)调用;更新的示例无法将WillCascadeOnDelete与WithMany链接,它不会编译,如果删除课程的。WillCascadeOnDelete(false)
调用从我当前的示例中,它仍然会给出错误?您使用ICollection
并使用配置属性WithMany(s=>s.Courses)
因此您不应收到冲突的多重性异常。最初,您指定了将导致该异常的.WithOptional()
。
[NotMapped]
public List<Student> Students {
get { return StudentCourses.Select(sc => sc.Student); }
}
modelBuilder.Entity<Department>()
.HasMany( d => d.Students )
.WithRequired()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Department>()
.HasMany( d => d.Courses )
.WithRequired()
.WillCascadeOnDelete( false );
modelBuilder.Entity<Course>()
.HasMany(u => u.Students)
.WithMany(s => s.Courses);