这里,我们将学习如何在Student实体和Course实体间配置多对多关系,Student可以参加很多Courses,并且多个学生可以加入同一个Course。
可以看下这篇文章, Entity Relationship 了解一下EF是如何管理实体间的一对一,一对多以及多对多关系的。
EF 6包含多对多关系的默认约定,你需要在两个实体间都包含集合类型的导航属性。例如:Student类应该包含一个集合类型的导航属性Course,同样Course类也应该包含一个集合类型的导航属性Student:
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);
}
}
EF API将会创建Students表和Courses表,同样还会创建联接表StudentCourses,StudentCourses表中,包含两个表中的主键作为主键以及外键:
注意:联接表的名称就是两个实体名称+后缀s.
上面的例子中,你已经看到了默认的约定为我们创建了多对多关系的表,以及相关的联接表。我们可以使用FLuent API来配置连接表的名称和列。
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()方法和WithMany()方法,用来给Student和Course实体配置多对多关系。Map()方法包含一个Action类型的委托,这里我们传入lambda,来定制联接表。MapLeftKey()用来指定Student表中的主键名称(因为我们从Student实体开始配置,所以Student是左表),MapRightKey()用来配置Course表中的主键名称,ToTable用来指定联接表的名称。
这样你就通过Fluent API重写了默认约定,配置了多对多关系。
13.翻译系列:Code-First方式配置多对多关系【EF 6 Code-First系列】
原文:https://www.cnblogs.com/caofangsheng/p/10691475.html