NHibernate之旅:探索查询之条件查询(CriteriaQuery)本节内容NHibernate中的查询方法条件查询(CriteriaQuery)o1.创建ICriteria实例o2.结果集限制o3.结果集排序o4.一些说明根据示例查询(QueryByExample)实例分析结语上一节,我们介绍了NHibernate查询语言的一种:NHibernate查询语言(HQL,NHibernateQueryLanguage),这一节介绍一下条件查询(CriteriaAPI)。NHibernate中的查询方法在NHibernate中提供了三种查询方式给我们选择:NHibernate查询语言(HQL,NHibernateQueryLanguage)、条件查询(CriteriaAPI,CriteriaQuery)、(根据示例查询(QBE,QueryByExample)是条件查询的一种特殊情况)、原生SQL(LiteralSQL,T-SQL、PL/SQL)。每个人有不同的喜好和特长,可以根据自己的情况选择使用其中的一种或几种。这一节我们介绍条件查询。条件查询(CriteriaQuery)HQL极为强大,但是有些人希望能够动态的使用一种面向对象API创建查询,而不是在.NET代码中嵌入字符串。在NHibernate中,提供了一种直观的、可扩展的CriteriaAPI。在我们键入查询语句的时候,提供了编译时的语法检查,VS提供了强大的智能提示。如果你对HQL的语法感觉不是很舒服的话,用这种方法可能更容易。这种API也比HQL更可扩展。典型用法:从ISession接口中创建ICriteria实例对象;在这个ICriteria实例对象上设置一个或多个表达式;要求ICriteria接口返回需要的列表,就是根据表达式从数据库中返回对象。注意:由于篇幅有限,我在这里仅仅贴出了数据访问层的代码。测试这些方法的代码就没有贴出来了,你可以下载本系列的源代码仔细看看测试这些方法的代码。这些实例我争取写出来可以运行起来,大家下载源码看看效果,一些数据需要按个人数据库里的数据情况修改。例如查询条件和结果。这节,我们在上一节源代码的基础上,在数据访问层中新建QueryCriteriaAPI.cs类用于编写条件查询方法,在数据访问的测试层新建一QueryCriteriaAPIFixture.cs类用于测试。1.创建ICriteria实例使用ISession接口的CreateCriteria方法创建了NHibernate.ICriteria接口一个特定的持久化类的查询实例,也可以说ISession是用来制造Criteria实例的工厂。publicIListCustomerCreateCriteria(){ICriteriacrit=_session.CreateCriteria(typeof(Customer));crit.SetMaxResults(50);IListCustomercustomers=crit.ListCustomer();returncustomers;}例如上面的例子返回Customer对象集合,设置最大的集合数量为50条。2.结果集限制使用ICriteria接口提供的Add方法添加Restrictions类中约束表达式可以限制一些结果集的作用。publicIListCustomerNarrowing(){IListCustomercustomers=_session.CreateCriteria(typeof(Customer)).Add(Restrictions.Like(Firstname,YJing%)).Add(Restrictions.Between(Lastname,A%,Y%)).ListCustomer();returncustomers;}3.结果集排序使用ICriteria.Order对结果集排序,第二个参数true代表asc,false代表desc。例如下面例子查询Customer对象按FirstName降序、Lastname升序。publicIListCustomerOrder(){return_session.CreateCriteria(typeof(Customer)).Add(Restrictions.Like(Firstname,Y%)).AddOrder(newNHibernate.Criterion.Order(Firstname,false)).AddOrder(newNHibernate.Criterion.Order(Lastname,true)).ListCustomer();}4.一些说明条件查询同样支持关联查询、动态关联抓取(在介绍一对多,多对多关系中阐述),投影、聚合和分组,离线(detached)查询和子查询是2.0版新增加的内容,以后在相关知识中介绍。也可以自行参考NHibernate参考文档13章。根据示例查询(QueryByExample)根据示例查询(QBE,QueryByExample)是条件查询的一种特殊情况,NHibernate.Criterion.Example类根据你指定的实例创造查询条件。其典型的用法:创建一个Example实例;在Example实例上设置值;根据Example和设置NHibernate返回其对象集合。例如下面的例子,按照指定Customer查询数据库里的记录:publicIListCustomerQuery(){CustomercustomerSample=newCustomer(){Firstname=YJing,Lastname=Lee};return_session.CreateCriteria(typeof(Customer)).Add(Example.Create(customerSample)).ListCustomer();}你可以自行调整Example使之更实用:publicIListCustomerUseQueryByExample_GetCustomer(CustomercustomerSample){Exampleexample=Example.Create(customerSample).IgnoreCase().EnableLike().SetEscapeCharacter('&');return_session.CreateCriteria(typeof(Customer)).Add(example).ListCustomer();}实例分析实例1:利用CriteriaAPI按Firstname和Lastname查询顾客。publicIListCustomerGetCustomersByFirstnameAndLastname(stringfirstname,stringlastname){return_session.CreateCriteria(typeof(Customer)).Add(Restrictions.Eq(Firstname,firstname)).Add(Restrictions.Eq(Lastname,lastname)).ListCustomer();}测试:调用GetCustomersByFirstnameAndLastname方法,查询Firstname为“YJing,Lastname为Lee的顾客,判断查询结果数量是否为1。(注:在数据库中有符合这一个记录)[Test]publicvoidGetCustomerByFirstnameAndLastnameTest(){IListCustomercustomers=_queryCriteriaAPI.GetCustomersByFirstnameAndLastname(YJing,Lee);Assert.AreEqual(1,customers.Count);}实例2:利用CriteriaAPI获取顾客ID大于CustomerId的顾客。publicIListCustomerGetCutomersWithIdGreaterThan(intcustomerId){return_session.CreateCriteria(typeof(Customer)).Add(Restrictions.Gt(CustomerId,customerId)).ListCustomer();}结语好了,通过2篇文章的介绍,对NHibernate中的查询语法有了大致了解,知道了NHibernate中两种最主要的查询方式,还有一种原生SQL查询,内容不多,请参考NHibernate官方文档吧。多多练习!下节将介绍对对象的操作。本系列链接:NHibernate之旅系列文章导航