频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

ORM中的继承关系映射全解

来源:it168 作者:teddyma 出处:巧巧读书 2007-10-19 进入讨论组
下一页 1 2 3 

   实体继承是基于OO和关系型数据库软件系统设计中的一个重要主题。本文通过基于NBear的实例解析ORM中的实体继承体系映射的方方面面。 

    单表继承体系

    所谓单表继承体系就是用一张数据库表存储整个继承体系中的所有实体的数据。单表继承体系适合那种继承体系中实体数目相对较少,总记录数相对较少,子类对父类的属性扩展也相对较少的情形。

    单表继承体系优点是读/写继承体系中的每个实体的数据,都只需操作一张表,性能较好,并且,新增继承类,或扩展实体属性都只需要增减一张表的字段就可以了,易于维护;主要缺点是,因为所有的实体共享一张表,表中会有比较多的NULL字段值的数据,浪费了一些存储空间,同时,如果记录数过多,表就会更庞大,也会影响表的读写性能。

    简单单表继承体系

    让我们先看一个假象的例子:

[Table("AllInOneTable")] public interface Parent : IEntity { [PrimaryKey] int ID { get; } string Name { get; set; } } [Table("AllInOneTable")] public interface AnotherParent : IEntity { [PrimaryKey] int ID { get; } int Age { get; set; } } [Table("AllInOneTable")] public interface Child : Parent, AnotherParent { [PrimaryKey] new int ID { get; set; } DateTime Birthday { get; set; } }

    我们可以看到,在上例中,我们定义了两个基实体Parent和AnotherParent,Child实体同时从两个基类继承。注意,代码中加粗的行,如果多个不同的基接口包含相同名称的属性,代码会编译失败,此时,需要像这样使用new关键字来避免编译失败。

    这里,我们采用的是单表继承体系方式,注意每个实体都映射到AllInOneTable这个表,只不过对每个实体来说,只使用了AllInOneTable表的部分字段。

    但是,以这样的简单方式定义单表继承时,因为从表中读数据时无法知道一行数据真正对应的是哪一个子类,所以,实际情况下,一般我们都要附加一些查询条件和字段默认值。

    带附加条件的单表继承体系

    采用单表继承体系方案时,继承体系中的不同子类不仅仅扩展父类的属性,肯定还会附带一些字段查询条件和默认值。这里会用到NBear.Common.TableAttribute的AdditionalWhere和AdditionalInsert属性,关于这两个属性的详细用法请参考表映射。

    请看下面的代码:

public interface Message : IEntity { [PrimaryKey] int ID { get; } string Title { get; set; } string Content { get; set; } DateTime UpdateTime { get; set; } } [Table("Message", AdditionalInsert = "[MessageType] = 1", AdditionalWhere = "[MessageType] = 1")] public interface CommonMessage : Message { int UserID { get; set; } } [Table("Message", AdditionalInsert = "[MessageType] = 2", AdditionalWhere = "[MessageType] = 2")] public interface SpecialMessage : Message { int GroupID { get; set; } }

    这里我们实际要持久化的是两个实体CommonMessage和SpecialMessage,他们有一个共同的抽象父类Message,父类作为一个抽象类不会被直接使用。我们将整个继承体系存于Message数据表。包含CommonMessage和SpecialMessage的所有属性。但是,就像我们在上面的假象示例中所说的,如果直接查询Message表,返回CommonMessage对应的字段数据,那么连SpecialMessage插入的那些数据也会被返回,反之亦然,这显然是不符合要求的。

    因此,我们需要定义附加的查询条件和插入默认值,即为Message表增加一个MessageType字段,该字段值为1的数据代表CommonMessage,值为2代表该行数据是SpecialMessage,如上面的代码中定义AdditionalWhere和AdditionalInsert后,查询CommonMessage或SpecialMessae时,就只会返回真正对应到他们的MessageType值的记录了;当插入数据时,为CommonMessage和SpecialMessage,框架也会自动为其设置必要的MessageType默认值。 

观看地址: http://www.qqread.com/csharp/b360536.html进入讨论组讨论。
下一页 1 2 3 
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章