• EF CodeFirst(四) 关系


    数据库表之间有一对一  一对多 多对多关系。那同样,CodeFirst也要能分析这些类之间的这些关系。
    CodeFirst可以自动通过分析类之间的属性导航属性 从而得出类之间的关系,自动确定外键。

    一对多
    一对多是最为常见的一种关系,符合怎样的规范会被CodeFirst识别为一对多的关系呢?
        public class Blog
        {
            public string ID { get; set; }
            public string BlogName { get; set; }
            public string BlogAuthor { get; set; }
            public virtual List <Post> Posts { get; set ; }      //导航属性          
            public virtual List <Article> Articles { get; set; }  //导航属性
            [ Timestamp]
            public byte [] version { get; set; }
        }
    
        public class Post
        {
            public string ID { get; set; }
            public string PostName { get; set; }
            public string Content { get; set; }
            public virtual Blog BelongBlog { get; set; }      //导航属性
        }
        public class Article
        {
            public string ID { get; set; }
            public string ArticleName { get; set; }
            public string Content { get; set; }
        }
    CodeFirst发现 Blog中有两个集合导航属性,Post中也有一个Blog类型的引用属性,分析出Blog和 Post以及Article之间都存在一对多的关系。
    我们还可以发现 Article中并没有 Blog类型的导航属性,并且 Post和Article生成的主键名称不一样。
    其实EF推断两个类之间存在一堆多的关系,只需要 两个类中的其中一个存在指向另一个类的导航属性即可。
    并且 外键名称的生成规则是 首先是 导航属性名称+ 下划线_ +ID 如果导航属性不存在 那就是 另一个类的类名+ID
     
    存在显示的符合规范的外键
    有些时候就是手贱,喜欢手动写上外键,那么属性名称符合什么样的规范会被CodeFirst识别为外键,而不是一般属性呢?(当然前提是已经存在导航属性)
    当属性符合 [目标类型的键名],[目标类型名称]+[目标类型键名称],或[导航属性名称]+[目标类型键名称]的形式的时候,会被判定为外键。
     
    当两个类之间存在多个关系时会怎样呢?在Post类中,有可能需要跟踪谁创建了它,以及谁编辑了它。那么Post类就需要增加两个导航属性
       public  Person CreatedBy { get; set; }
            public  Person UpdatedBy { get; set; }
    那同样在我们的Person类之中,也需要加上两个属性,一个属性指向这个人创建的所有文章,另一个属性指向之个人更新的所有文章。
     public virtual List<Post> PostsWritten { get; set; }
            public virtual List <Post> PostsUpdated { get; set ; }

    会发现这时候生成了四个外键,这是因为当类之间存在多个关系的时候,EF是无法准确分辨的,需要我们手动的添加代码来帮助EF分析。要想解决这个问题 就要用另一个数据注释 : InverseProperty 代码赢改成如下
            [InverseProperty( "CreatedBy")]
            public virtual List <Post> PostsWritten { get; set ; }
            [ InverseProperty("UpdatedBy" )]
            public virtual List <Post> PostsUpdated { get; set ; }
    要注意 InverseProperty括号内的名称是要与另一个类的相关的导航属性名称相匹配的,否则会报错。
    这个时候数据库外键就正确了


    多对多
    如果两个类之间,各自都有集合导航属性指向对方,那这两个类之间的关键会被识别为多对多关系。
     public class Student
        {
            public int StudentID { get; set; }
            public string Name { get; set; }
            public List <Course> Courses { get; set ; }
        }
        public class Course
        {
            public int CourseID { get; set; }
            public string CourseName { get; set; }
            public List <Student> Students { get; set ; }
        }
    学生可以选择多门课程,每门课也有很多学生,这样的多对对关系,codefirst会自动生成第三张表,表里存放另外两张表的主键作为外键存放。


    一对一
    在一对一和一对多的关系之后,我们回头再来讲一对一的关系。
    如果需要将两个类之间的关系配置为一对一的关系,那么需要两个类互相有指向对方的引用属性
      public class Book
        {
            public int BookID { get; set; }
            public string Name { get; set; }
            public BookCover Cover { get; set; }
        }
    
        public class BookCover
        {
            [ Key , ForeignKey ("Coverof" )]
            public int BookID { get; set; }
            public byte [] Photo { get; set; }
            public Book Coverof { get; set; }
        }
    并且两个类的主键要是一样的,而且为了确认其中一个为关系中的依赖主体,必须用ForeignKey指明,也就是上面的BookCover表的BookID既是外键也必须是主键。否则会报错。
     
    关系就讲到这里,如果喜欢就 推荐一下吧~ O(∩_∩)O
  • 相关阅读:
    RPC细谈
    RPC浅谈
    动态规划
    libco 的定时器实现: 时间轮
    一次HTTP请求的完整过程——协议篇(DNS、TCP、HTTP)
    多个CPU、多核CPU以及超线程(Hyper-Threading)
    Linux下which、whereis、locate、find命令的区别
    warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
    使用OutputDebugString输出调试信息
    VS或windows用代码产生GUID
  • 原文地址:https://www.cnblogs.com/JasonShenW/p/5097814.html
Copyright © 2020-2023  润新知