NHibernate系列文章二十三:NHibernate查询之Criteria查询(附程序下载)
摘要
上一篇文章介绍了NHibernate HQL,他的缺点是不能够在编译时发现问题。如果数据库表结构有改动引起了实体关系映射的类有改动,要同时修改这些HQL字符串。这篇文章介绍NHibernate面向对象的Criteria查询。他提供了很多API接口,可以实现“私人订制”式的面向对象查询。
作为对照,本篇文章将上篇文章的八个HQL查询全部用Criteria查询写一遍,读者可以自己感受下他们之间的区别。
本篇文章的代码可以到NHibernate查询下载
1、创建Criteria对象,查询所有Customer对象信息
public IList<Customer> QueryAllCriteria()
{
return Session.CreateCriteria<Customer>().List<Customer>();
}
ISession.CreateCriteria方法返回持久化查询对象的ICriteria实例,他是使用Criteria查询的第一步。传入一个类型参数,表示是对哪一个实体类持久化对象的查询实例。List方法返回持久化类的所有对象。
2、CreateAlias方法创建别名
public IList<Customer> QueryAllCriteria()
{
return Session.CreateCriteria<Customer>()
.CreateAlias("Customer", "c").List<Customer>();
}
3、指定对象返回数组
public IList<int> SelectIdCriteria()
{
IList<int> ids = Session.CreateCriteria(typeof(Customer))
.SetProjection(Projections.Distinct(Projections.ProjectionList().Add(Projections.Property("Id"))))
.List<int>();
return ids;
}
ICriteria.SetProjection方法将应用投影到查询中,Projections有很多静态方法生成Distinct、GroupBy、Max、Min、Avg、Sum等投影。
4、添加查询条件
public IList<Customer> GetCustomerByNameCriteria(string firstName, string lastName)
{
return Session.CreateCriteria<Customer>()
.Add(Restrictions.And(
Restrictions.Eq("FirstName", firstName), Restrictions.Eq("LastName", lastName))
).List<Customer>();
} public IList<Customer> GetCustomersStartWithCriteria()
{
var list = Session.CreateCriteria<Customer>().Add(Restrictions.Like("FirstName", "J%")).List<Customer>();
return list.ToList();
}
ICriteria.Add方法用来添加where条件,Restrictions类提供了很多生成查询条件的API方法。
Restrictions.And方法和Restrictions.Or方法对应SQL的and和or条件,可以传入多个条件对象拼接and/or子句,可以灵活地使用括号进行分组。
示例中的Restrictions.Eq方法和Restrictions.Like方法是最常用的Restrictions方法API。
此外,Restrictions还提供Between、Ge、Gt、Le、Lt、In、IsNotNull、IsNull、Where等多个API方法,可以满足生成大部分查询条件。
5、order by
public IList<Customer> GetCustomersOrderByCriteria()
{
var list = Session.CreateCriteria<Customer>().AddOrder(new NHibernate.Criterion.Order("FirstName", true)).List<Customer>();
return list.ToList();
}
ICriteria.AddOrder方法添加order子句,传入Criteria.Order对象。Criteria.Order类构造函数传入两个参数,第一个参数表示对哪个属性进行排序,第二个字段表示是升序还是降序,true是升序,false是降序。
6、关联查询
1)按分组查询客户Id及客户关联的订单数量
public IList<object[]> SelectOrderCountCriteria()
{
var query = Session.CreateCriteria(typeof(Customer)).CreateCriteria("Orders")
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("Id"))
.Add(Projections.RowCount()));
return query.List<object[]>();
}
对查询进行分组通用的代码是:
var query = Session.CreateCriteria(typeof(类名))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("属性名"))
.Add(Projections.RowCount() | Projections.Max("Max投影属性名") | Projections.Sum("Sum投影属性名")));
因为要对Order记录进行分组统计,所以使用CreateCriteria("Orders")创建与Orders的关联。
2)查询在指定日期到当前内所有下订单客户信息
public IList<Customer> GetCustomersOrderDateGreatThanCriteria(DateTime orderDate)
{
return Session.CreateCriteria<Customer>().CreateCriteria("Orders").Add(Restrictions.Gt("Ordered", orderDate))
.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())
.List<Customer>();
}
ICriteria.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer())的结果相当于对HQL查询使用了distinct子句。
3)查询所有订单数量大于2的客户信息
public IList<Customer> GetCustomersOrderCountGreaterThanCriteria()
{
var query = Session.CreateCriteria(typeof(Customer)).CreateCriteria("Orders")
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("Id"))
.Add(Projections.RowCount()));
IList<object[]> groups = query.List<object[]>(); IList<int> ids = groups.Where(g => (int)g[] > ).Select(g => (int)g[]).ToList(); return Session.CreateCriteria(typeof(Customer))
.Add(Restrictions.In("Id", ids.ToArray<int>()))
.List<Customer>();
}
因为ICriteria目前不支持对Group分组结果进行Having筛选,因此必须先对Customer和Orders的关联查询以Customer.Id进行分组,得到Customer.Id和Order数量作为属性的对象的集合,对这个集合执行linq查询,得到订单数量大于2的客户Id集合,最后用Restrictions.In方法对Customer对象集合进行筛选,选出Customer.Id在订单数量大于2的客户Id集合内的客户信息。这样就能够实现Having的查询功能。
结语
NHibernate Criteria查询优点是完全面向对象,ICriteria对象提供了大量的API函数实现完全面向对象的查询语句。可以在编译时发现问题。在更改实体类属性后(如果改动不大),不怎么需要修改查询语句。缺点是功能有限,写复杂的分组查询和条件查询比较困难。一般情况下,在写简单查询的时候用Criteria查询,在写复杂查询的时候使用HQL或者Linq to NHibernate。
NHibernate系列文章二十三:NHibernate查询之Criteria查询(附程序下载)的更多相关文章
- NHibernate系列文章二十五:NHibernate查询之Query Over查询(附程序下载)
摘要 这一篇文章介绍在NHibernate 3.2里引入的Query Over查询,Query Over查询跟Criteria查询类似.首先创建IQueryOver对象,然后通过调用该对象的API函数 ...
- NHibernate系列文章二十二:NHibernate查询之HQL查询(附程序下载)
摘要 NHibernate提供了多种查询方式,最早的HQL语言查询.Criteria查询和SQL Query,到NHibernate 3.0的Linq NHibernate,NHIbernate 4. ...
- NHibernate系列文章二十六:NHibernate查询之SQL Query查询(附程序下载)
摘要 NHibernate在很早的版本就提供了SQL Query(原生SQL查询),对于很复杂的查询,如果使用其他的查询方式实现比较困难的时候,一般使用SQL Query.使用SQL Query是基于 ...
- NHibernate系列文章二:创建NHibernate工程
摘要 这篇文章介绍了如何创建一个简单的使用NHibernate的控制台应用程序,包括使用NuGet.简单的配置.单表映射.对NHibernate配置文件添加智能提示.使用ISessionFactory ...
- NHibernate系列文章二十一:延迟加载
摘要 NHibernate的延迟加载机制是很重要的内容.通过关系映射将数据库表之间的关系映射成对象之间的关系,如果没有延迟加载机制,从主表的一个对象的查询将直接查询出所有与该对象关联的其他对象,如果关 ...
- NHibernate系列文章一:NHibernate介绍
摘要 NHibernate是一个成熟的开源的面向对象的.net映射框架.大量的实际项目中正在使用该框架.他是建立在ADO.Net基础之上.目前的版本是NHibernate 4.0.4.本系列文章都是基 ...
- NHibernate系列文章九:NHibernate对象二级缓存上
摘要 NHibernate的二级缓存由SessionFactory管理,由所有Session共享. NHibernate缓存读取顺序: 首先从一级缓存中读取,如果一级缓存对象存在,则读取一级缓存对象并 ...
- NHibernate系列文章十七:NHibernate Session管理(附程序下载)
摘要 NHibernate的Session的管理涉及到NHibernate的两个最重要的对象ISessionFactory和ISession.ISessionFactory的生成非常消耗资源,通常都在 ...
- NHibernate系列文章八:NHibernate对象一级缓存
摘要 Nhibernatea缓存非常强大,按照缓存存储在Session对象还是SessionFactory对象分为一级缓存和二级缓存. 一级缓存存在于Session对象里,也叫Session缓存,由S ...
随机推荐
- HTML的文本格式化
文本格式化:<html> <body> <b>This text is bold</b> <br /> <strong>This ...
- Python-SocketServer源码
贴到博客,地铁上看- """Generic socket server classes. This module tries to capture the various ...
- 嵌入式系统添加无线wifi模块
开发环境:fl2440开发板,linux3.0内核,交叉编译器路径/opt/buildroot-2011.11/arm920t/usr/bin/arm-linux-,无线网卡RT3070 平时开发板联 ...
- nginx入门篇----功能特性
1.nginx功能特性 可以作为http服务器或者反向代理服务器 能够快速响应静态页面(html)的请求 支持FastCGI.SSL.Virtual Host.URL Rewrite.HTTP.Gzi ...
- 怎么使用CDR中排列对象功能
通过将对象发送到其他对象的前面或者后面,可以更改图层或页面上对象的堆叠顺序,还可以将对象按堆叠顺序精确定位,并且可以反转多个对象的堆叠顺序.本教程将详解CorelDRAW中排列对象各按钮功能. 1. ...
- js获取ip地址
方法三(所有的平台及浏览器):使用的搜狐接口 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></scrip ...
- Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义
一.Java中什么叫做引用类型变量?引用:就是按内存地址查询 比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...
- oracle 职业学习指引
风哥 它是阿里巴巴造出的概念.其本意是,在阿里巴巴的IT架构中,去掉IBM的小型机.Oracle数据库.EMC存储设备,代之以自己在开源软件基础上开发的系统. 思科.IBM.谷歌.高通.英特尔.苹果. ...
- 在Ubuntu上安装LAMP服务器
1.安装Ubuntu上安装LAMP apt-get install lamp-server^ 2.安装过程中设置MySql密码 3.测试 创建index.php var/www/html/index. ...
- .NET批量删除代码前的行号
1 EmEditor Pro.EditPlus .visual studio ,把有行号的代码粘贴进去,按住键盘的Alt键,然后用鼠标拖出选择框列选行号,最后按Delete删除行号; 2 使用正则 ...