EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

前言

α角 与 β角

关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split
本篇会继续有关于β角的彩蛋在等着大家去发掘。/斜眼笑

其他

  • 本篇的程序,可以在 https://github.com/kentliu2007/EFCoreDemo/tree/master/InheritanceWithEntitySplit 下载。建议大家可以下载之后对照着程序来阅读本篇(我用的是VS2017)。

  • 由于篇幅比较长,为了方便阅读,本篇分成两个部分。如果耐着性子看完第一部分,而不是处女座/不是DB First er的,可以止步,不需要继续看第二部分了。

需求

我们先来看看需求:

  • 某校园的一个人员资料系统,其中可登录用户有两种:教师和学生。每个可登录用户具有以下属性:

    • 用户登录名 (该系统用户的唯一标识值)

    • 密码

  • 教师。系统需要记录 教师 的以下属性:

    • 教职工号码 (某校园里,该教师的唯一标示值)

    • 工资级别 (自编的工资级别)

  • 学生。系统需要记录 学生 的以下属性:

    • 学生编号 (某校园里,该学生的唯一标示值)

    • 学生就读年级

逻辑设计

根据上述需求,我们会有以下这样的类的设计:
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
上述设计还有一个一点点不同的版本:
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

物理设计

从逻辑设计到物理设计,会由于我们选择的具体的实现方式而产生一定的偏差。例如,不同厂商的数据库引擎,或者不选用数据库引擎而选用其他的产品(MQ或者NoSQL类产品),甚至不同的ORM产品,都会引致偏差的发生。

用EF6怎么实现

下面我们从DB First er的角度,直接根据上述的逻辑设计,设计出数据表。然后再看看用EF6如何实现。

数据表

EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Users的索引
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Students的索引
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Teachers的索引
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • FK_Students_Users的设置
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • FK_Teachers_Users的设置
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

EF Model

在各种wizard的帮助下,****后,我们需要做一些小改动,删掉某些Property,以及Navigation Property,然后把 Inheritance 关系拉好。并且转换一下 User.UserType为Enum UserTypes。
于是我们就有了这样的 EF Model:
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
(第一个β角的彩蛋,我们根据习惯,通常会把UserType设置为Enum。这个和逻辑设计有一点点偏差)
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

程序
  • Solution
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Unit Test
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • 测试数据
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

EF6对类的继承提供了支持,所以从类到表,然后再到EF,一切都很顺其自然,一气呵成。

用EFCore怎么实现

EFCore也提供类的继承的支持,可以在这里查看微软的文档:https://docs.microsoft.com/zh-cn/ef/core/modeling/inheritance ,以及 https://docs.microsoft.com/zh-cn/ef/core/modeling/relational/inheritance
由于EFCore更加倾向于Code First,所以我们按照文档来走一遍,然后对本篇的需求,就会有以下的产出:

程序
  • Solution
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • User、Student和Teacher的程序

    public partial class User
    {        public string LoginName { get; set; }        public string FirstName { get; set; }        public string LastName { get; set; }        public string Password { get; set; }
    }    public partial class Student : User
    {        public string StudentCode { get; set; }        public int GradeLevel { get; set; }
    }    public partial class Teacher : User
    {        public string StaffCode { get; set; }        public int SalaryGrade { get; set; }
    }
  • DBContext的程序
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Unit Test程序
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

数据表

有了上述的程序,我们跑一下Migration命令,于是就有以下的表结构

  • Migration命令
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • 表结构
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

  • Users的索引
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

没有其他表了?真的没有了。用EF Core的正向工程,上述的三个父子类,它就是生成这样一个数据表,就够了。当然DBA还可能对数据表做一点改动,例如 主键不要是 聚集索引等。不过基于不骗篇幅的借口,让我们偷一下懒吧。 :-P
(第二个β角的彩蛋出现了。由于我们选用了 EF Core,物理设计的数据表,竟然和逻辑设计有着喇么大的偏差)

  • 测试数据
    EFCore Lazy Loading + Inheritance = 干净的数据表 (一)

好吧,看起来用EFCore来实现类的继承也很简单。一切操作只需要按照教程一步步捣弄,也很直接方便。

本篇结语

上面就是EF6 和 EFCore分别怎样支持 类的继承的做法。如果你是Code First er,可以止步于此了。
如果你是处女座,或者 DB First er,

  • 你会发现EFCore正向工程后的数据表,表结构很特别,且看着测试数据的结果,会感觉是一堵装饰墙。反正就是总觉得有说不出来的违和感。

  • 你会想,有没有可能,让EFCore,用上和逻辑设计之间β角偏差最小的数据表呢?

如果你有上述的感觉和疑问,欢迎继续看下一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】。

相关文章:

原文地址:https://www.cnblogs.com/fatkent/p/10396596.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
EFCore Lazy Loading + Inheritance = 干净的数据表 (一)