EF自我理解: 一對一 一對多 多對多


一,一對一關系。

如:一個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里面去:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM