本文以双鱼座同学的再说继承关系一文中提到的一组三元继承关联关系为基础。
首先,分别实现本人的ORM中的继承关系映射全解一文中提到的三种实体继承体系到关系数据库的映射方案实例。
接着,使用接口分离以上继承体系中的实体类中的相同概念,对该继承体系进行重构,并同样给出对重构后的继承体系的三种到关系数据库的映射方案实例。
全部实例代码基于NBear的接口式实体定义方式实现。
1. 背景
首先,给出双鱼座同学原文中的三元继承关联关系的等价接口定义。见下图1:
2. 对图1-1的ORM映射
2.1 单表继承体系
采用单表继承体系映射时,我们用一个AllInOne表包含所有实体的所有字段,并用一个FilterMark过滤标志,区分该条纪录的类型,注意只有所有的User,包括抽象的User和所有的UserGroup是可以查询的,其余接口仅仅用于概念抽象。
代码1
[Table(IsView = true)]
public interface PrivilegeOwner : IEntity
{
[PrimaryKey]
int Id { get; }
string Name { get; set; }
}
[Table("AllInOne", AdditionalWhere = "FilterMark <= 20", IsView = true)]
public interface User : PrivilegeOwner
{
}
[Table("AllInOne", AdditionalInsert = "FilterMark = 1", AdditionalWhere = "FilterMark = 1")]
public interface LocalUser : User
{
string LoginId { get; set; }
string Password { get; set; }
}
[Table("AllInOne", AdditionalInsert = "FilterMark = 2", AdditionalWhere = "FilterMark = 2")]
public interface AgentUser : User
{
string LoginId { get; set; }
}
[Table("AllInOne", AdditionalInsert = "FilterMark = 3", AdditionalWhere = "FilterMark = 3")]
public interface GhostUser : User
{
}
[Table("AllInOne", AdditionalInsert = "FilterMark = 21", AdditionalWhere = "FilterMark = 21")]
public interface UserGroup : PrivilegeOwner
{
string Comment { get; set; }
}
2.2 一实体一具体表
采用一实体一具体表思路进行映射时,要为每个继承层次中的具体的实体定义一个重复包含所有父类字段的表,并在保存数据时,同时,更新字表和所有的父表。表示抽象契约的接口,在每个实现类包含一份重复字段定义,不需为这样的接口定义独立的表。
代码2
[Table("PrivilegeOwner")]
public interface PrivilegeOwner : IEntity
{
[PrimaryKey]
int Id { get; }
string Name { get; set; }
}
[Table("User")]
public interface User : PrivilegeOwner
{
}
[Table("LocalUser")]
public interface LocalUser : User
{
string LoginId { get; set; }
string Password { get; set; }
}
[Table("AgentUser")]
public interface AgentUser : User
{
string LoginId { get; set; }
}
[Table("GhostUser")]
public interface GhostUser : User
{
}
[Table("UserGroup")]
public interface UserGroup : PrivilegeOwner
{
string Comment { get; set; }
}
2.3 一实体一扩展表
采用一实体一扩展表思路进行映射时,注意将表示真正的继承概念中的基类或子类分离为独立的表,而将表示抽象契约的接口,在每个实现类包含一份重复字段定义,不需为这样的接口定义独立的表。对于没有扩展任何基类的属性的子类,也至少需要包含一个Id字段和它的父类关联。注意每一个XXXExtedned实体对应了实体扩展表相对于父类扩展的字段,而不带Extended后缀的表则大多是代表逻辑实体的视图。
代码3
[Table("P
|