EF6基礎系列(五)---EF中的實體關系
這一節將總結EF是怎麽管理實體之間的關系。
EF與數據庫一樣支持三種關系類型:①一對一 ,②一對多,③多對多。
下邊是一個SchoolDB數據庫的實體數據模型,圖中包含所有的實體和各個實體間的關系。通過設計器我們很容易看出實體間的對應關系
1.一對一
如上圖,Student和StudentAddress具有一對一的關系(零或一)。一個學生只能有一個或零個地址。實體框架將Student實體導航屬性添加到StudentAddress實體中,將StudentAddress實體導航屬性添加到Student實體中。同時,StudentAddress類中將StudentId作為PrimaryKey和ForeignKey屬性,這樣Student和StudentAddress就成為一對一的關系。
public partial class Student { public Student() { this.Courses = new HashSet<Course>(); } public int StudentID { get; set; } public string StudentName { get; set; } public Nullable<int> StandardId { get; set; } public byte[] RowVersion { get; set; } //實體導航屬性 public virtual StudentAddress StudentAddress { get; set; } } public partial class StudentAddress { //同時是主鍵和外鍵 public int StudentID { get; set; } public string Address1 { get; set; } public string Address2 { get; set; } public string City { get; set; } public string State { get; set; } //實體導航屬性 public virtual Student Student { get; set; } }
在上面的示例中,StudentId屬性在StudentAddress類中是同時是PrimaryKey和ForeignKey。我們可以在context的OnModelCreating方法中使用Fluent API進行配置。
2.一對多
Standard與Teacher實體具一對多的關系。這表示多個教師可以處在一個級別,而每個教師只能有一個級別。
public partial class Standard { public Standard() { this.Teachers = new HashSet<Teacher>(); } public int StandardId { get; set; } public string StandardName { get; set; } public string Description { get; set; } //集合導航屬性 public virtual ICollection<Teacher> Teachers { get; set; } } public partial class Teacher { public Teacher() { this.Courses = new HashSet<Course>(); } public int TeacherId { get; set; } public string TeacherName { get; set; } public Nullable<int> TeacherType { get; set; } //外鍵 public Nullable<int> StandardId { get; set; } //實體導航屬性 public virtual Standard Standard { get; set; } }
Standard實體具有集合導航屬性 Teachers (請註意它是復數),這表明Standard可以有一個教師集合(許多教師)。而Teacher實體具有Standard實體導航屬性,表明Teacher只有一個相關聯Standard,同時Teacher中包含StandardId外鍵。這樣Standard與Teacher就成為了一對多的關系。
3.多對多關系
Student和Course具有多到多關系。這表示一個學生可以參加許多課程,而一個課程也可以向許多學生講授。
數據庫包括StudentCourse中間表,表中只包含Student和Course的主鍵。
如上圖所示,Student實體包含集合導航屬性 Courses,Course實體包含集合導航屬性 Students以表示它們之間的多對多關系。這兩個表都沒有外鍵關系,它們通過StudentCourse中間表進行關聯。
下面的代碼片段展示了Student和Course實體類。
public partial class Student { public Student() { this.Courses = new HashSet<Course>(); } public int StudentID { get; set; } public string StudentName { get; set; } public Nullable<int> StandardId { get; set; } public byte[] RowVersion { get; set; } //集合導航屬性 public virtual ICollection<Course> Courses { get; set; } } public partial 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; } }
註:實體框架在中間表僅有兩個表的主鍵(只有StudentId和CourseId)時才自動維護多對多關系。當我們給Student添加一個Course或給Course添加一個Student,執行SaveChange()時,EF會在中間表自動會插入對應的StudentId和CourseId。如果中間表包含其他列,那麽EDM也會為中間表創建實體,EF不再自動維護中間表,那麽我們就需要手動管理多對多實體的CRUD操作。
EF6基礎系列(五)---EF中的實體關系