這一節將總結EF是怎麼管理實體之間的關係。
EF與數據庫同樣支持三種關係類型:①一對一 ,②一對多,③多對多。html
下邊是一個SchoolDB數據庫的實體數據模型,圖中包含全部的實體和各個實體間的關係。經過設計器咱們很容易看出實體間的對應關係數據庫
如上圖,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進行配置。post
Standard與Teacher實體具一對多的關係。這表示多個教師評同一個級別(成績級別A,B,C,D),而每一個教師只能評一個級別,如給學生1評A級的同時不能再評一個B級。this
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能夠有一個教師集合(老師1和老師2均可以給A級的評分)。而Teacher實體具備Standard實體導航屬性,代表每一個Teacher只能評一個Standard,同時Teacher中包含StandardId外鍵。這樣Standard與Teacher就成爲了一對多的關係。spa
Student和Course具備多到多關係。這表示一個學生能夠參加許多課程,而一個課程也能夠向許多學生講授。
數據庫包括StudentCourse中間表,表中只包含Student和Course的主鍵。
如上圖所示,Student實體包含集合導航屬性 Courses,Course實體包含集合導航屬性 Students以表示它們之間的多對多關係。這兩個表都沒有外鍵關係,它們經過StudentCourse中間表進行關聯。設計
下面的代碼片斷展現了Student和Course實體類。code
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操做。htm
EF系列目錄連接:Entity Franmework系列教程彙總blog