在NHibernate的单表继承模式下通过父类Repository查询子类

在NHibernate中经常遇到继承与关系数据库的ORMapping的问题,我之前的一篇博客(http://www.cnblogs.com/studyzy/archive/2011/08/16/2140675.html)介绍了有3种常用的实现方式:

  • Concrete Table Inheritance(具体表继承)
  • Single Table Inheritance(单表继承)
  • Class Table Inheritance(类表继承)

其中单表继承是我个人比较常用比较推荐的做法。使用单表继承可以不用Join多个表查询效率高,而且在Domain Model的属性提示到父类或者下降到子类时,数据库模型不用更改。其缺点就是一个数据表的列比较多,而且很多列为空,不过现代的数据库对空列的压缩处理已经比较好了,不会产生大量空列造成的性能问题和磁盘空间的浪费。

在NHibernate中经常会遇到通过父类的Repository来查询子类的情况,比如现在有一个抽象的Employee对象,下面有OfficeUser和Teacher两个具体的对象,这两个对象都有其特有的属性,比如Teacher会有所领导的班级,而OfficeUser却没有。我们可以将OfficeUser和Teacher都保存到Employee表中,然后建立了一个EmployeeRepository,使用Employee作为Query的入口,那么如果要查询Employee表中所有的Teacher该怎么查呢?下面分别用QueryOver、Criteria和HQL来说明:

  • QueryOver查询Employee表中的所有Teacher:
Session.QueryOver<Employee>().Where(a =>a.GetType() == typeof (Teacher)).List();

这里需要注意的是,条件中使用的是a.GetType()==typeof(Teacher),但是不能使用a is Teacher,虽然这在C#中是一回事,但是NHibernate会对其理解不一样,所以必须这么写,否则查询不出来。

  • Criteria查询Employee表中的所有Teacher:
var cri = Session.CreateCriteria<Employee>();
cri= cri.Add(Expression.Eq("class",typeof(Teacher)));
var ems = cri.List<Employee>();
这里需要注意的是class关键字。必须这么写,不能写成大写的Class,也不能换成其他字,只有这样才能让NHibernate理解,并正确返回结果。
  • HQL查询Employee表中的所有Teacher:
 var cri = Session.CreateQuery("from Employee where Type='Teacher'"); var ems = cri.List<Employee>();

这里又不一样了,where条件后面跟的“Type”是Employee表的Discriminator,是一个列名,也就是通过这一列来区分Employee表的每一条数据到底是OfficeUser还是Teacher。所以,如果你的Discriminator Column是Abc,那么HQL就要写成from Employee where Abc='Teacher'。

以上是以最简单了例子说明了如果通过父类查询具体的子类的方法,实际项目中肯定比这个查询要复杂,但是只要记住了这三种查询的要点,结合其他条件就可以写出NHibernate能够理解的查询。

时间: 2024-08-30 13:18:14

在NHibernate的单表继承模式下通过父类Repository查询子类的相关文章

ORM中的继承关系映射全解——单表继承体系、一实体一具体表、一实体一扩展表

ORM中的继承关系映射全解--单表继承体系.一实体一具体表.一实体一扩展表.接口映射 本文涉及的内容包括: 1.单表继承体系 2.一实体一具体表 3.一实体一扩展表 4.接口实现映射vs基类继承映射 1.单表继承体系 所谓单表继承体系就是用一张数据库表存储整个继承体系中的所有实体的数据.单表继承体系适合那种继承体系中实体数目相对较少,总记录数相对较少,子类对父类的属性扩展也相对较少的情形. 单表继承体系优点是读/写继承体系中的每个实体的数据,都只需操作一张表,性能较好,并且,新增继承类,或扩展实

eclipse + JBoss 5 + EJB3开发指南(10):通过继承实体Bean,将单个表映射成多个表(单表策略,SINGLE_TABLE)

本文为原创,如需转载,请注明作者和出处,谢谢! 上一篇:eclipse + JBoss 5 + EJB3开发指南(9):实现Entity Bean的多对多(many-to-many)映射     如果以前使用过EJB1.x或EJB2.x的实体Bean,会发现无法通过继承实体Bean将单个表分成多表.而在EJB3中,我们很容易实现这个功能.先看看图1所示的表结构和记录. 图1   t_accounts表的结构和记录 在t_accounts表中,有一个account_type字段.这个字段是一个长度

Ext form表单加载时 下拉框取值的问题

问题描述 Ext form表单加载时 加载的数据 后台传的的是id号,下拉框匹配的时候匹配当该id的name可是现在有个问题,当表单加载完成 下拉框的数据还没加载完成 这时下拉框显示的id,不是name只有当下拉框数据源先加载完 表单数据后加载完 才显示的是name.....有人说 给下拉框数据源添加 load事件 在load事件方法里面 给组件赋值:Ext.getCmp("组件Id").set(value).可是这个value 是form表单里jsonreade里的 我怎么能方便的取

单用户模式下mount -o remount,rw / 有大用途

单用户模式下mount -o remount,rw / 有大用途         我们的Linux系统在无法启动时候,通常需要进入单用户模式下进行修改一些配置文件,或调整一些参数方可.但是在进入单用户模式后,我们的/文件系统是只读模式,无法进行修改,那么这个时候我们就需要用到一条命令:mount –o remount,rw / 这个命令来让我们的/路径文件系统为可读模式,这样就可以实现自由修改了. 例如: 增加了/etc/mtab /dev/sdb1 /install ext3 rw 0 0 /

解析:使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象

原文:解析:使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象 之前开发时遇到的一个问题,使用easyui的form提交表单,在Chrome下时没问题的,但是在IE下出现类似附件下载时提示是否保存的现象. 这里记录一下如何解决的.其实这个现象不光是easyui的form,还有其他一些form插件也是一样的,使用不当就会遇到这个问题.   前台: <!DOCTYPE html> <html> <head> <meta http-equi

access数据库-Access中创建分割窗体,加入到水平标签或设计视图模式下后,看不到下半的数据表视图

问题描述 Access中创建分割窗体,加入到水平标签或设计视图模式下后,看不到下半的数据表视图 如题,用access2010给数据表创建了分割窗体,但切换成设计视图后,为什么只有上半部分的窗体视图而没有下半部分的数据视图? 同样的,为方便多窗口统一管理,将此分割窗体加入到 "窗体"选项卡->"导航"->"水平标签"中后,在窗口说也是只能显示上半部分. 请问,如何才能将分割窗口上下两部分同时显示在水平标签的统一管理窗口中,多谢!

Linux学习之CentOS(二十二)--进入单用户模式下修改Root用户的密码_Linux

在上一篇随笔里面详细讲解了Linux系统的启动过程.,我们知道Linux系统的启动级别一共有6种级别,通过 /etc/inittab 这个文件我们就能看到: [root@xiaoluo ~]# cat /etc/inittab # inittab is only used by upstart for the default runlevel. # # ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # #

用SQL进行单表查询

  单表查询是相对多表查询而言的,指从一个数据表中查询数据.4.2.1 查询所有的记录    在[命令编辑区]执行输入"select * from scott.emp",然后单击[执行]按钮,出现如图4.3所示的emp数据表所有记录.    [参见光盘文件]:\第4章\4.2\421.sql.    select * from 数据表,这里的"*"代表数据表中所有的字段.4.2.2 查询所有记录的某些字段    在[命令编辑区]输入"select empn

jsp+javabean开发模式下,数据库sql语句的编写规范

js|规范|数据|数据库|语句 在中小型的开发团队或开发项目中,很多人选择了jsp+javabean的开发模式,但这种模式下,sql语句应该写在什么位置,很多人,包括我自己都会走很多的弯路.        很多书上要么推荐sql语句写在bean中,让jsp调用即可(理由是这样子比较规范),要么推荐sql语句写在jsp文件中(理由是方便开发,开发速度很快),但我在实际开发中,发现采用上述两种方式都不是很好,下面我将我的方法说一下,希望得到大家的指正.        我认为在做列表查询时,即按照某种