zoukankan      html  css  js  c++  java
  • 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里面去:

  • 相关阅读:
    Android开发之Sqlite的使用
    ZOJ 3607 Lazier Salesgirl
    ZOJ 3769 Diablo III
    ZOJ 2856 Happy Life
    Ural 1119 Metro
    Ural 1146 Maximum Sum
    HDU 1003 Max Sum
    HDU 1160 FatMouse's Speed
    Ural 1073 Square Country
    Ural 1260 Nudnik Photographer
  • 原文地址:https://www.cnblogs.com/visibleisfalse/p/10774150.html
Copyright © 2011-2022 走看看