摘要

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查询(附程序下载)的更多相关文章

  1. NHibernate系列文章二十:NHibernate关系之一对一(附程序下载)

    摘要 NHibernate一对一关系虽然不经常碰到,但是在对于数据库结构优化的时候,经常会碰到一对一关系.比如,产品详细信息比较多的时候,可以把产品详细信息放到另一张表里面,Product主表只记录产 ...

  2. NHibernate系列文章二十二:NHibernate查询之HQL查询(附程序下载)

    摘要 NHibernate提供了多种查询方式,最早的HQL语言查询.Criteria查询和SQL Query,到NHibernate 3.0的Linq NHibernate,NHIbernate 4. ...

  3. NHibernate系列文章二十五:NHibernate查询之Query Over查询(附程序下载)

    摘要 这一篇文章介绍在NHibernate 3.2里引入的Query Over查询,Query Over查询跟Criteria查询类似.首先创建IQueryOver对象,然后通过调用该对象的API函数 ...

  4. NHibernate系列文章二十四:NHibernate查询之Linq查询(附程序下载)

    摘要 NHibernate从3.0开始支持Linq查询.写Linq to NHibernate查询就跟写.net linq代码一样,非常灵活,可以很容易实现复杂的查询.这篇文章使用Linq to NH ...

  5. NHibernate系列文章二十三:NHibernate查询之Criteria查询(附程序下载)

    摘要 上一篇文章介绍了NHibernate HQL,他的缺点是不能够在编译时发现问题.如果数据库表结构有改动引起了实体关系映射的类有改动,要同时修改这些HQL字符串.这篇文章介绍NHibernate面 ...

  6. NHibernate系列文章二十八:NHibernate Mapping之Auto Mapping(附程序下载)

    摘要 上一篇文章介绍了Fluent NHibernate基础知识.但是,Fluent NHibernate提供了一种更方便的Mapping方法称为Auto Mapping.只需在代码中定义一些Conv ...

  7. NHibernate系列文章二十七:NHibernate Mapping之Fluent Mapping基础(附程序下载)

    摘要 从这一节起,介绍NHibernate Mapping的内容.前面文章都是使用的NHibernate XML Mapping.NHibernate XML Mapping是NHibernate最早 ...

  8. NHibernate系列文章二:创建NHibernate工程

    摘要 这篇文章介绍了如何创建一个简单的使用NHibernate的控制台应用程序,包括使用NuGet.简单的配置.单表映射.对NHibernate配置文件添加智能提示.使用ISessionFactory ...

  9. NHibernate系列文章二十一:延迟加载

    摘要 NHibernate的延迟加载机制是很重要的内容.通过关系映射将数据库表之间的关系映射成对象之间的关系,如果没有延迟加载机制,从主表的一个对象的查询将直接查询出所有与该对象关联的其他对象,如果关 ...

随机推荐

  1. MySQL文件目录格式及存放位置

    了解MYSQL的都知道,在MYSQL中建立任何一张数据表,在其数据目录对应的数据库目录下都有对应表的.frm文件,.frm文件是用来保存每个数据表的元数据(meta)信息,包括表结构的定义等,.frm ...

  2. js---html---body标签

    <body bgcolor="背景颜色" background="背景图片" text="文本颜色" link="连接文件颜 ...

  3. 循环数据forin,foreach,for of

    最近一直在对数据处理,循环匹配之类的,我的mentor也已经多次指出一个问题,就是在循环里面用if去判断一个数值是否存在的时候,只要找到就要退出,这个时候就要对循环的语法提出了要求: 1.for in ...

  4. linux命令:less

    1.命令介绍: less用来逐页输出文件内容,less相比more功能更加强大,less可以前后翻页,前后搜索. 2.命令格式: less [选项] 文件 3.命令参数: -b <缓冲区大小&g ...

  5. gulp ---攻略一

    根据项目需要可能会出连载 项目需要现在用gulp进行js的质量检测.合并.压缩.发布,未来需要进行sass的编译.合并.压缩,html.img的压缩以及md5戳.reload等功能,暂时先测试js的质 ...

  6. 苹果IPhone手机由于更新了IOS7 Beta测试版导致“激活出错”后,如何还原电话本和照片方法

    苹果这狗日的,手段果然狠,因为用户提前升级了测试版又没有更新正式版,就突然把手机变砖头,既不让升级正式版,也不让备份手机中的信息,确实有必要这样吗? 我的手机是IPone4s,在看了6月Apple W ...

  7. 多线程 or 多进程?[转]

    在Unix上编程采用多线程还是多进程的争执由来已久,这种争执最常见到在C/S通讯中服务端并发技术的选型上,比如WEB服务器技术中,Apache是 采用多进程的(perfork模式,每客户连接对应一个进 ...

  8. Visual Studio 2012+jQuery-1.7.1

    今天用Visual Studio 2012开发一个网站项目,在集成jqplot图表控件并进行调试的时候(使用的是MVC4框架),加载网页绘制图表的时候总是报错(提示$.jqplot.barRender ...

  9. java 后台校验格式

    package com.hengxin.qianee.utils; import java.net.InetAddress; public class RegexUtils { /** * 用户名是否 ...

  10. LintCode Binary Tree Maximum Path Sum

    Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. ...