本节,我们将学习如何配置Student 和Course 实体类之间的多对多关系。Student 可以加入多个Course ,多个Student 可以加入一门Course 。
使用DataAnnotation配置多对多关系:
Student类应该有Course 的集合导航属性,Course 应该有Student的集合导航属性,这将创建Student和Course 之间的多对多关系,如下所示:
public class Student { public Student() { this.Courses = new HashSet<Course>(); } public int StudentId { get; set; } [Required] public string StudentName { get; set; } public virtual ICollection<Course> Courses { get; set; } } public class Course { public Course() { this.Students = new HashSet<Student>(); } public int CourseId { get; set; } public string CourseName { get; set; } public virtual ICollection<Student> Students { get; set; } }
下面是包括Student和Course实体的上下文类:
public class SchoolDBContext : DBContext { public SchoolDBContext() : base("SchoolDB-DataAnnotations") { } public DbSet<Student> Students { get; set; } public DbSet<Course> Courses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } }
当我们使用上下文类执行一些操作时,上面代码将创建以下数据库。
Code-First将创建Student,Caurse和StudentCourses三张表。 StudentCourses表将包括其他两个表的主键Student_StudentId 和 Course_CourseId,如下所示:
注意:连接表的名称将是具有后缀“s”的两个表的名称。
使用Fluent API配置多对多关系:
你可以使用Fluent API配置Student和Course之间的多对多关系,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasMany<Course>(s => s.Courses) .WithMany(c => c.Students) .Map(cs => { cs.MapLeftKey("StudentRefId"); cs.MapRightKey("CourseRefId"); cs.ToTable("StudentCourse"); }); }
上面的例子中看到,.HasMany <Course>(s => s.Courses).WithMany(c => c.Students)设置Student与Course有了多对多的关系,通过各自实体中的导航属性。
Map方法采用Action类型委托,因此,我们可以传递lambda表达式。其中,我们将指定Student的FK属性名称(我们从Student实体开始,因此将为left表)和Course表的FK属性名称。.ToTable将创建StudentCourse表。
这样将创建一个新的表StudentCourse与两个主键,也将是外键,如下所示:
注意:上面的Map()函数中的ToTable()方法指定了连接表的名称。