一,一對一關系。
如:一個student,對應一個studentDetail。
1,student類:
public class Student : FullAuditedAggregateRoot<long> { public virtual StudentDetail StudentDetail { get; set; }//包含一個studentDetail的導航屬性后 EF會給兩個表形成主外鍵關系。 }
2,studentDetail類
public class StudentDetail : FullAuditedAggregateRoot<long> { }
3,生成的表結構如下:
A表中的一個字段,是B表的主鍵,那他就可以是A表的外鍵。在這里,student表中,有一個字段是studentDetail表的主鍵,所以這個字段就是student表的外鍵。
二,一對多關系。
如:一個班級有多個學生。
1,student類:
public class Student : FullAuditedAggregateRoot<long> { public virtual StudentDetail StudentDetail { get; set; } public virtual BJClass BJClass { get; set; }//加這個方便訪問student的時候把班級信息點出來 } }
2,班級類
/// <summary> /// 班級 /// </summary> public class BJClass : FullAuditedAggregateRoot<long> { public virtual ICollection<Student> Students { get; set; } }
3,生成的表結構:
student表:
班級表:
4,一對多中,一的那一方,要不要加上對多的那一方的導航屬性?
比如:student類中,要不要加上 班級BJClass,加上跟不加對表結構生成有沒有影響?
為了驗證,這里增加一個student1類,跟上面student類只有一個地方不同,那就是沒加BJClass的導航屬性,注釋掉了。
public class Student1 : FullAuditedAggregateRoot<long> { public virtual StudentDetail StudentDetail { get; set; } // public virtual BJClass1 BJClass1 { get; set; } //注釋掉 } }
班級不變,只是改了類名:
/// <summary> /// 班級1 /// </summary> public class BJClass1 : FullAuditedAggregateRoot<long> { public virtual ICollection<Student1> Students { get; set; } }
生成的表結構:
班級表:
結論:在一對多關系中,在一 的那一方,加不加 多 的那一方的導航屬性,對表結構的生成是沒有影響的。
三,多對多。
如:一個學生可以有多門課程 一門課程可以被多個學生學習
學生表:
/// <summary> /// 學生表 /// </summary> public class Student : FullAuditedAggregateRoot<long> { public virtual StudentDetail StudentDetail { get; set; } public virtual BJClass BJClass { get; set; } public virtual ICollection<Course> Courses { get; set; } }
課程表:
/// <summary> /// 課程表 /// </summary> public class Course : FullAuditedAggregateRoot<long> { public virtual ICollection<Student> Students { get; set; } }
多對多,雙方各自包含另一方的集合導航屬性,數據庫默認會生成中間表,生成的表結構如下:
這樣生成的中間表,基本可以滿足大部分的多對多的需求,但是如果有需要在中間表中添加一些字段,則這種根據EF默認配置的方法顯然是無法滿足的。
查了網上資料,說出了默認配置之外,還可以用FluentApi對中間表進行配置,但FluentApI配置的方式現在很多人都沒怎么用過。
既然我們要在中間表增加字段,那我們為什么不直接自己配置中間表呢?就不需要EF幫我們做默認配置了。
多對多默認配置思路:
1,新建類A,A中包含B的集合導航屬性
2,新建類B,B中也包含A的集合導航屬性
3,EF默認生成中間表AB(但生成的中間表只是默認包含A的id以及B的id,無法按需添加字段)
多對多手動配置中間表思路:
1,新建中間表類AB,按需添加自己需要的字段。
2,新建類A,A中包含中間表AB的集合導航屬性(不是包含B)
3,新建類B,B中同樣包含中間表AB的集合導航屬性。
示例:
一份同意書可以對應多個小服務,一個小服務可以被多個同意書選擇。
中間表:
/// <summary> /// 自己配置中間表 /// </summary> public class ConsentFormeSmallService2 { /// <summary> /// 小服務id /// </summary> [Required] public virtual long ConsentFormeSmallService2Id { get; set; } /// <summary> /// 自己新增的字段 /// </summary> public virtual long MyFiled { get; set; } }
同意書表:
/// <summary> /// 同意書表 /// </summary> public class ConsentForme : AuditedEntity<long> { public ICollection<ConsentFromeItem> ConsentFromeItem { get; set; } // public ICollection<ConsentFormeSmallService> ConsentFormeSmallService { get; set; } public ICollection<ConsentFormeSmallService2> ConsentFormeSmallService2 { get; set; } }
小服務表:
/// <summary> /// 小服務表 /// </summary> public class SmallService : AuditedEntity<long> { // public ICollection<ConsentFormeSmallService> ConsentFormeSmallService { get; set; } public ICollection<ConsentFormeSmallService2> ConsentFormeSmallService2 { get; set; } }
生成的表結構,這里只看中間表:
如上所示,中間表中包含兩個外鍵,分別是同意書表、小服務表的id。同時 還有自己按需添加的MyFIled字段,實現了中間表的按需添加。
如果不直接操作中間表,則可以不需要寫到DBContext里面去: