请注明转载地址:http://www.cnblogs.com/arhat
在上一章中,老魏讲述了HQL的链接查询,本章呢,老魏开始讲述HQL的子查询。子查询在SQL中也是占据着非常重要的作用,如果没有子查询,则有些特殊的需求我们是无法满足的。好了,废话不多说了,开始本章的旅行。
首先NHibenrate对于子查询有着一个非常重要的要求:“HQL中,子查询必须出现在where子句中,并且以一对圆括号包围”。这条规矩希望大家能够牢记在心中。
比如,我们现在要查询出,班级人数大于2的班级名称。那么HQL语句如下:
from Clazz c where c.CId in (selec s.Clazz.CId from Student s group by s.Clazz.CID having count(*)>2)
我们来试着执行一下,代码如下:
static void Main(string[] args) { string hql = "from Clazz c where c.CId in (select s.Clazz.CId from Student as s group by cid having count(*)>2)"; Model.Clazz clazz = DAL.NHibernateHelper.CreateQuery(hql, null).UniqueResult<Model.Clazz>(); Console.WriteLine("人数大于2的班级是:"+clazz.CName); }
运行结果如下:
从结果中,我们得到了我们想要的,同时NHibernate的确生成了子查询。但是NHibernate为HQL语句提供了几个HQL函数,可以帮助我们方便的解决这个问题,我们再把这个HQL语句更改一下:
string hql = "from Clazz as c where size(c.Students)>2";
这里我们会发现,虽然结果相同,但是生成的SQL语句不通,而HQL提供的size()函数是把集合属性作为参数的。当然了,HQL还提供了minelement(), maxelement(), minindex(), maxindex()等函数。
现在我们需要查询年龄为60的学生所在的班级。HQL语句如下:
string hql = "from Clazz as c where 60 in (select s.SAge from Student as s where s.Clazz.CId = c.CId)";
执行结果如下:
从上面的几个例子中,我们了解了HQL语句对自查训的要求,不过,在使用子查询的过程中,我们还使用到了HQL的导航语法,比如where s.Clazz.CId = c.CId。本身在Student对象中没有Cid字段的,但是这里又需要,所以可以使用Student对象对父对象Clazz的引用来得到和Student关联的cid值。从上面的结果可以看出,最终HQL语句使用的还是Student表中的Cid和Clazz表中的CId.
不过话说回来了,HQL的子查询,说实在的老魏在一开始都比较蒙,可能因为习惯了SQL,导致在对对象查询的时候有点不知所措啊。以后还得多多练习。
那么本章就讲到这里了,大家多多练习吧!