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

  • 相关阅读:
    Java8简单的本地缓存实现
    Java堆内存详解
    拖拽实现备忘:拖拽drag&拖放drop事件浅析
    微信小程序下拉刷新PullDownRefresh的一些坑
    ES6里let、const、var区别总结
    nodejs大文件分片加密解密
    node+js实现大文件分片上传
    大文件上传前台分片后后台合并的问题
    fs.appendFileSync使用说明,nodejs中appendFile与writeFile追加内容到文件区别
    JS中的单线程与多线程、事件循环与消息队列、宏任务与微任务
  • 原文地址:https://www.cnblogs.com/visibleisfalse/p/10774150.html
Copyright © 2011-2022 走看看