前言
α角 与 β角###
关于α角 与 β角的介绍,请见上文 如何用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还可能对数据表做一点改动,例如 主键不要是 聚集索引等。不过基于不骗篇幅的借口,让我们偷一下懒吧。