上一篇文章我們講解了EF中的一對對多的關係映射,這篇文章我們講解EF中的多對多(Many-to-Many Relationship)關係映射。這篇文章我們同樣通過一個簡單的例子來講解多對多的關係映射。
零、自動生成關係表
故事:在一個學生選課系統中,存在學生和課程兩個實體,他們之間的關係是:一個學生可以選擇多門課程,一門課程也可以被多個學生選擇。
通過上面簡單的描述,我們可以分析出學生和課程是多對多的關係。這種關係應設在數據庫中就需要第三張表來輔助維持。這個第三張表被稱爲關聯表或鏈接表,這張表中存存儲了學生和課程的主鍵(或被能夠區分唯一性的字段)。現在我們看一下,通過代碼怎麼來表示多對多關係:
//學生類
public class Student:BaseEntity
{
public string Name { get; set; }
public int Age { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
//課程類
public class Course : BaseEntity
{
public string Name { get; set; }
public string TeacherName { get; set; }
public virtual ICollection<Student> Students { get; set; }
}
//基礎類
public class BaseEntity
{
public int Id { get; set; }
public DateTime CreateDateTime { get; set; }
}
同上一篇文章一樣,我們創建 Student 和 Course 的映射類
//學生映射類
public class StudentsMap : EntityTypeConfiguration<Student>
{
public StudentsMap()
{
//表名稱
ToTable("Students");
//主鍵
HasKey(p => p.Id);
//設置主鍵自增長
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//設置要映射的數據
Property(p => p.Name).HasColumnType("VARCHAR").HasMaxLength(50);
Property(p => p.Age);
Property(p => p.CreateDateTime);
//設置關係
HasMany(p => p.Courses)
.WithMany(p => p.Students)
.Map(p => p.ToTable("StudentCourses")
.MapLeftKey("StudentId")
.MapRightKey("CourseId"));
}
}
//課程映射類
public class CourseMap : EntityTypeConfiguration<Course>
{
public CourseMap()
{
ToTable("Coureses");
HasKey(p => p.Id);
Property(p => p.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.Name).HasColumnType("VARCHAR").HasMaxLength(50);
Property(p => p.TeacherName);
Property(p => p.CreateDateTime);
}
}
從上面的 學生映射類 可以看出,一個學生可以選擇多門課程,一個課程可以被多名學生選擇。我們爲了實現學生和課程多對多的關係,於是定義了關聯表,並且設置了這個關聯表中兩個外鍵的名稱。
注:
- 在設置多對多關係的時候,如果不定義 MapLeftKey 和 MapRightKey EF將默認使用 實體類型_id 。在本例中如果不定義這兩個鍵的名稱的話,EF默認使用的名稱是 Student_Id 和 Courses_Id;
- MapLeftKey 是關係鍵
下面我們編寫一段代碼來測試一下數據庫生成的是否是多對多的關係:
static void Main(string[] args)
{
using (var efContext = new EFContext())
{
Student student = new Student
{
Name = "張三",
Age = 26,
CreateDateTime = DateTime.Now,
Courses = new List<Course>
{
new Course
{
Name="語文",
TeacherName="王老師",
CreateDateTime=DateTime.Now
},
new Course
{
Name="數學",
TeacherName="孫老師",
CreateDateTime=DateTime.Now
}
}
};
Course course = new Course
{
Name = "英語",
TeacherName = "Jack",
CreateDateTime = DateTime.Now,
Students = new List<Student>
{
new Student
{
Name="王五",
Age=27,
CreateDateTime=DateTime.Now
},
new Student
{
Name="孫琦",
Age=27,
CreateDateTime=DateTime.Now
}
}
};
efContext.Students.Add(student);
efContext.Courses.Add(course);
efContext.SaveChanges();
}
}
代碼運行後,數據庫將出現三張表 Students 、 Coureses 和 StudentCourses ,其中 StudentCourses 是 關聯表 ,該表中將出現 Students 和 Coureses 之間的關係