前言
α角 与 β角
关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split。
本篇会继续有关于β角的彩蛋在等着大家去发掘。/斜眼笑
其他
- 本篇的程序,可以在 https://github.com/kentliu2007/EFCoreDemo/tree/master/InheritanceWithEntitySplit 下载。建议大家可以下载之后对照着程序来阅读本篇(我用的是VS2017)。 
- 由于篇幅比较长,为了方便阅读,本篇分成两个部分。如果耐着性子看完第一部分,而不是处女座/不是DB First er的,可以止步,不需要继续看第二部分了。 
需求
我们先来看看需求:
- 某校园的一个人员资料系统,其中可登录用户有两种:教师和学生。每个可登录用户具有以下属性: - 用户登录名 (该系统用户的唯一标识值) 
- 姓 
- 名 
- 密码 
 
- 教师。系统需要记录 教师 的以下属性: - 教职工号码 (某校园里,该教师的唯一标示值) 
- 工资级别 (自编的工资级别) 
 
- 学生。系统需要记录 学生 的以下属性: - 学生编号 (某校园里,该学生的唯一标示值) 
- 学生就读年级 
 
逻辑设计
根据上述需求,我们会有以下这样的类的设计:
上述设计还有一个一点点不同的版本:
物理设计
从逻辑设计到物理设计,会由于我们选择的具体的实现方式而产生一定的偏差。例如,不同厂商的数据库引擎,或者不选用数据库引擎而选用其他的产品(MQ或者NoSQL类产品),甚至不同的ORM产品,都会引致偏差的发生。
用EF6怎么实现
下面我们从DB First er的角度,直接根据上述的逻辑设计,设计出数据表。然后再看看用EF6如何实现。
数据表

- Users的索引   
- Students的索引   
- Teachers的索引   
- FK_Students_Users的设置  
- FK_Teachers_Users的设置  
EF Model
在各种wizard的帮助下,逆向工程后,我们需要做一些小改动,删掉某些Property,以及Navigation Property,然后把 Inheritance 关系拉好。并且转换一下 User.UserType为Enum UserTypes。
于是我们就有了这样的 EF Model:


(第一个β角的彩蛋,我们根据习惯,通常会把UserType设置为Enum。这个和逻辑设计有一点点偏差)

程序
- Solution  
- Unit Test  
- 测试数据  
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  
- 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的程序  
- Unit Test程序  
数据表
有了上述的程序,我们跑一下Migration命令,于是就有以下的表结构
- Migration命令  
- 表结构  
- Users的索引  
没有其他表了?真的没有了。用EF Core的正向工程,上述的三个父子类,它就是生成这样一个数据表,就够了。当然DBA还可能对数据表做一点改动,例如 主键不要是 聚集索引等。不过基于不骗篇幅的借口,让我们偷一下懒吧。 :-P
(第二个β角的彩蛋出现了。由于我们选用了 EF Core,物理设计的数据表,竟然和逻辑设计有着喇么大的偏差)
- 测试数据  
好吧,看起来用EFCore来实现类的继承也很简单。一切操作只需要按照教程一步步捣弄,也很直接方便。
本篇结语
上面就是EF6 和 EFCore分别怎样支持 类的继承的做法。如果你是Code First er,可以止步于此了。
如果你是处女座,或者 DB First er,
- 你会发现EFCore正向工程后的数据表,表结构很特别,且看着测试数据的结果,会感觉是一堵装饰墙。反正就是总觉得有说不出来的违和感。 
- 你会想,有没有可能,让EFCore,用上和逻辑设计之间β角偏差最小的数据表呢? 
如果你有上述的感觉和疑问,欢迎继续看下一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】。
相关文章:
- Shadow Properties之美(一)【Microsoft Entity Framework Core随笔】 
- Shadow Properties之美(二)【Microsoft Entity Framework Core随笔】 
- “幕后英雄”之Backing Fields【Microsoft Entity Framework Core随笔】 
- 如何用EFCore Lazy Loading实现Entity Split 
原文地址:https://www.cnblogs.com/fatkent/p/10396596.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 