NHibernate系列文章二十六:NHibernate查询之SQL Query查询(附程序下载)
摘要
NHibernate在很早的版本就提供了SQL Query(原生SQL查询),对于很复杂的查询,如果使用其他的查询方式实现比较困难的时候,一般使用SQL Query。使用SQL Query是基于原生的SQL语句,查询后将结果做投影到NHibernate实体类对象的过程。也可以投影到其他任何.net集合类。
本篇文章的代码可以到NHibernate查询下载
1、from子句
public IList<Customer> GetAllSQL()
{
return Session.CreateSQLQuery("select * from Customer").AddEntity(typeof(Customer)).List<Customer>();
}
首先创建调用ISession.CreateSQLQuery方法,传入原生的SQL语句,生成ISQLQuery对象,这是使用SQL Query的第一步。
ISQLQuery.AddEntity方法传入类型参数,将查询结果映射到Customer类。
ISQLQuery.List方法立即执行,返回查询结果。
2、as子句提供别名,as可以省略
public IList<Customer> GetAllSQL()
{
return Session.CreateSQLQuery("select * from Customer as c").AddEntity(typeof(Customer)).List<Customer>();
}
3、指定列返回数组
public IList<int> SelectIdSQL()
{
return Session.CreateSQLQuery("select distinct c.Id from Customer c")
.AddScalar("Id", NHibernateUtil.Int32)
.List<int>();
}
ISQLQuery.AddScalar方法将查询语句的列映射到.net数据类型,传入的第一个参数是列名,第二个参数是类型,NHibernateUtil类中的公开了很多静态实例对象表示映射数据类型,这里使用Int32。
4、where子句
public IList<Customer> GetCustomerByNameSQL(string firstName, string lastName)
{
return Session.CreateSQLQuery("select * from Customer where FirstName = :firstName and LastName = :lastName")
.AddEntity(typeof(Customer))
.SetString("firstName", firstName)
.SetString("lastName", lastName)
.List<Customer>();
} public IList<Customer> GetCustomersStartWithSQL()
{
return Session.CreateSQLQuery("select * from Customer where FirstName like 'J%'")
.AddEntity(typeof(Customer))
.List<Customer>();
}
SQL Query的查询参数传递跟HQL参数传递是一样的。而且这里是使用原生的SQL语句,比HQL更方便。
5、order by子句
public IList<Customer> GetCustomersOrderBySQL()
{
return Session.CreateSQLQuery("select * from Customer c order by c.FirstName")
.AddEntity(typeof(Customer))
.List<Customer>();
}
6、关联查询
/// <summary>
/// 按分组查询客户Id及客户关联的订单数量
/// </summary>
/// <returns></returns>
public IList<object[]> SelectOrderCountSQL()
{
return Session.CreateSQLQuery("select c.Id, count(*) as OrderCount from Customer c inner join [Order] o on c.Id=o.CustomerId group by c.Id")
.AddScalar("Id", NHibernateUtil.Int32)
.AddScalar("OrderCount", NHibernateUtil.Int32)
.List<object[]>();
} /// <summary>
/// 查询所有订单数量大于2的客户信息
/// </summary>
/// <returns></returns>
public IList<Customer> GetCustomersOrderCountGreaterThanSQL()
{
string sql = @"select * from Customer
where Id in
(
select c.Id from Customer c inner join [Order] o on c.Id = o.CustomerId
group by c.Id
having count(*) > 2
)";
return Session.CreateSQLQuery(sql)
.AddEntity(typeof(Customer))
.List<Customer>();
} /// <summary>
/// 查询在指定日期到当前时间内有下订单的客户信息
/// </summary>
/// <param name="orderDate"></param>
/// <returns></returns>
public IList<Customer> GetCustomersOrderDateGreatThanSQL(DateTime orderDate)
{
return Session.CreateSQLQuery("select distinct c.* from Customer c inner join [Order] o on c.Id=o.CustomerId where o.Ordered > :orderDate")
.AddEntity(typeof(Customer))
.SetDateTime("orderDate", orderDate)
.List<Customer>();
}
注意这几个方法都是传入的原生SQL语句,不管多复杂的查询,只要会写SQL语句,就能够使用SQL Query返回对象集合。
如果是多个表的联合查询,返回结果的字段来自不同的表,这种情况我一般是使用Hashtable映射。使用SetResultTransformer(Transformers.AliasToEntityMap)将结果映射成EntityMap,然后调用List<Hashtable>()方法返回查询结果,查询方法返回的结果类型是IList<Hashtable>。
ISQLQuery.SetResultTransformer(Transformers.AliasToEntityMap)
结语
对于复杂的多表联合查询,以及复杂的分组查询,应该使用SQL Query,因为使用它更方便,而且不容易出错。虽然在效率上,比使用其他的方式要略低。但是前提是项目只打算用SQL Server数据库或只用Oracle数据库,因为是使用的原生SQL语句,而SQL Server数据库和Oracle数据库在写查询的时候还是有很多语法上的差别。
NHibernate系列文章二十六:NHibernate查询之SQL Query查询(附程序下载)的更多相关文章
- NHibernate系列文章二十:NHibernate关系之一对一(附程序下载)
摘要 NHibernate一对一关系虽然不经常碰到,但是在对于数据库结构优化的时候,经常会碰到一对一关系.比如,产品详细信息比较多的时候,可以把产品详细信息放到另一张表里面,Product主表只记录产 ...
- NHibernate系列文章二十二:NHibernate查询之HQL查询(附程序下载)
摘要 NHibernate提供了多种查询方式,最早的HQL语言查询.Criteria查询和SQL Query,到NHibernate 3.0的Linq NHibernate,NHIbernate 4. ...
- NHibernate系列文章二十五:NHibernate查询之Query Over查询(附程序下载)
摘要 这一篇文章介绍在NHibernate 3.2里引入的Query Over查询,Query Over查询跟Criteria查询类似.首先创建IQueryOver对象,然后通过调用该对象的API函数 ...
- NHibernate系列文章二十四:NHibernate查询之Linq查询(附程序下载)
摘要 NHibernate从3.0开始支持Linq查询.写Linq to NHibernate查询就跟写.net linq代码一样,非常灵活,可以很容易实现复杂的查询.这篇文章使用Linq to NH ...
- NHibernate系列文章二十三:NHibernate查询之Criteria查询(附程序下载)
摘要 上一篇文章介绍了NHibernate HQL,他的缺点是不能够在编译时发现问题.如果数据库表结构有改动引起了实体关系映射的类有改动,要同时修改这些HQL字符串.这篇文章介绍NHibernate面 ...
- NHibernate系列文章二十八:NHibernate Mapping之Auto Mapping(附程序下载)
摘要 上一篇文章介绍了Fluent NHibernate基础知识.但是,Fluent NHibernate提供了一种更方便的Mapping方法称为Auto Mapping.只需在代码中定义一些Conv ...
- NHibernate系列文章二十七:NHibernate Mapping之Fluent Mapping基础(附程序下载)
摘要 从这一节起,介绍NHibernate Mapping的内容.前面文章都是使用的NHibernate XML Mapping.NHibernate XML Mapping是NHibernate最早 ...
- NHibernate系列文章二:创建NHibernate工程
摘要 这篇文章介绍了如何创建一个简单的使用NHibernate的控制台应用程序,包括使用NuGet.简单的配置.单表映射.对NHibernate配置文件添加智能提示.使用ISessionFactory ...
- NHibernate系列文章二十一:延迟加载
摘要 NHibernate的延迟加载机制是很重要的内容.通过关系映射将数据库表之间的关系映射成对象之间的关系,如果没有延迟加载机制,从主表的一个对象的查询将直接查询出所有与该对象关联的其他对象,如果关 ...
随机推荐
- 没有好看的 Terminal 怎么能够快乐地写代码
换了好几回Terminal默认的配色,真是难看哭了,作为一只有生活追求的序媛,当然不能安(zuo)之(yi)若(dai)素(bi)了 1 自定义 Terminal问候语 sudo pico /etc/ ...
- The differences between Java application and Java applet
在Java语言中,能够独立运行的程序称为Java应用程序(Application).Java语言还有另外一种程序--Applet程序.Applet程序(也称Java小程序)是运行于各种网页文件中,用于 ...
- [20150925]Linux之文件系统与SHELL
Linux之文件系统与SHELL 文件系统介绍 ext2/ext3/ext4 Ext2是GNU/Linux系统中标准的文件系统.这是Linux中使用最多的一种文件系统,它是专门为Linux设计的,拥有 ...
- hdu4737 A Bit Fun ——O(n)做法、错误的做法 + 正确做法
囧== 下面的做法是错误的.下午在路上突然明白了== 哎,到现在还是只知道暴力的做法,囧爆了:http://www.cnblogs.com/liuxueyang/p/3322197.html 类似于前 ...
- C++实现不能被继承的类——终结类 分类: C/C++ 2015-04-06 14:48 64人阅读 评论(0) 收藏
1. 问题 C++如何实现不能被继承的类,即终结类.Java中有final关键字修饰,C#中有sealed关键字修饰,而C++目前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现. ...
- VC++ ADO相关
<VC对ADO的操作> ADO概述: ADO是Microsoft为最新和最强大的数据访问范例 OLE DB 而设计的,是一个便于使用的应用程序层接口. ADO 使您能够编写应用程序以通过 ...
- MSSQL 创建自定义异常
创建时,必须先创建英文的,否则会报错:必须添加此消息的 us_english 版本后,才能添加 '简体中文' 版本. EXEC sp_addmessage 50001, 15, 'option wro ...
- Activity和Service是否是在同一个进程中运行。
一般情况下,Activity和Service在同一个包名内,并且没有设定属性android:process=":remote",两者在同一个进程中. 因为一个进程只有一个UI线程, ...
- 【转】Linux CentOS内核编译:下载CentOS源码、编译2.6.32-220的错误(apic.c:819 error 'numi_watchdog' undeclared)
一.下载CentOS源码 1.1 查看CentOS版本 cat /etc/issue 1.2 查看Linux内核版本 uname -r 1.3 下载 文件名:kernel-2.6.32-220.el6 ...
- SQL 表 和字符串 互转 (行列互转)
-- 表转字符串 )) ,,'') --字符串转表 ),)) ,) )) AS BEGIN DECLARE @StartIndex INT --开始查找的位置 DECLARE @FindIndex I ...