zoukankan      html  css  js  c++  java
  • NHibernate系列文章二十六:NHibernate查询之SQL Query查询(附程序下载)

    摘要

    NHibernate在很早的版本就提供了SQL Query(原生SQL查询),对于很复杂的查询,如果使用其他的查询方式实现比较困难的时候,一般使用SQL Query。使用SQL Query是基于原生的SQL语句,查询后将结果做投影到NHibernate实体类对象的过程。也可以投影到其他任何.net集合类。

    本篇文章的代码可以到NHibernate查询下载

    1、from子句

    1         public IList<Customer> GetAllSQL()
    2         {
    3             return Session.CreateSQLQuery("select * from Customer").AddEntity(typeof(Customer)).List<Customer>();
    4         }

    首先创建调用ISession.CreateSQLQuery方法,传入原生的SQL语句,生成ISQLQuery对象,这是使用SQL Query的第一步。

    ISQLQuery.AddEntity方法传入类型参数,将查询结果映射到Customer类。

    ISQLQuery.List方法立即执行,返回查询结果。

    2、as子句提供别名,as可以省略

    1         public IList<Customer> GetAllSQL()
    2         {
    3             return Session.CreateSQLQuery("select * from Customer as c").AddEntity(typeof(Customer)).List<Customer>();
    4         }

    3、指定列返回数组

    1         public IList<int> SelectIdSQL()
    2         {
    3             return Session.CreateSQLQuery("select distinct c.Id from Customer c")
    4                 .AddScalar("Id", NHibernateUtil.Int32)
    5                 .List<int>();
    6         }

    ISQLQuery.AddScalar方法将查询语句的列映射到.net数据类型,传入的第一个参数是列名,第二个参数是类型,NHibernateUtil类中的公开了很多静态实例对象表示映射数据类型,这里使用Int32。

    4、where子句

     1         public IList<Customer> GetCustomerByNameSQL(string firstName, string lastName)
     2         {
     3             return Session.CreateSQLQuery("select * from Customer where FirstName = :firstName and LastName = :lastName")
     4                 .AddEntity(typeof(Customer))
     5                 .SetString("firstName", firstName)
     6                 .SetString("lastName", lastName)
     7                 .List<Customer>();
     8         }
     9 
    10         public IList<Customer> GetCustomersStartWithSQL()
    11         {
    12             return Session.CreateSQLQuery("select * from Customer where FirstName like 'J%'")
    13                 .AddEntity(typeof(Customer))
    14                 .List<Customer>();
    15         }

    SQL Query的查询参数传递跟HQL参数传递是一样的。而且这里是使用原生的SQL语句,比HQL更方便。

    5、order by子句

    1         public IList<Customer> GetCustomersOrderBySQL()
    2         {
    3             return Session.CreateSQLQuery("select * from Customer c order by c.FirstName")
    4                 .AddEntity(typeof(Customer))
    5                 .List<Customer>();
    6         }

    6、关联查询

     1      /// <summary>
     2         /// 按分组查询客户Id及客户关联的订单数量
     3         /// </summary>
     4         /// <returns></returns>
     5         public IList<object[]> SelectOrderCountSQL()
     6         {
     7             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")
     8                 .AddScalar("Id", NHibernateUtil.Int32)
     9                 .AddScalar("OrderCount", NHibernateUtil.Int32)
    10                 .List<object[]>();
    11         }
    12 
    13         /// <summary>
    14         /// 查询所有订单数量大于2的客户信息
    15         /// </summary>
    16         /// <returns></returns>
    17         public IList<Customer> GetCustomersOrderCountGreaterThanSQL()
    18         {
    19             string sql = @"select * from Customer
    20 where Id in
    21 (
    22     select c.Id from Customer c inner join [Order] o on c.Id = o.CustomerId
    23     group by c.Id
    24     having count(*) > 2
    25 )";
    26             return Session.CreateSQLQuery(sql)
    27                 .AddEntity(typeof(Customer))
    28                 .List<Customer>();
    29         }
    30 
    31         /// <summary>
    32         /// 查询在指定日期到当前时间内有下订单的客户信息
    33         /// </summary>
    34         /// <param name="orderDate"></param>
    35         /// <returns></returns>
    36         public IList<Customer> GetCustomersOrderDateGreatThanSQL(DateTime orderDate)
    37         {
    38             return Session.CreateSQLQuery("select distinct c.* from Customer c inner join [Order] o on c.Id=o.CustomerId where o.Ordered > :orderDate")
    39                 .AddEntity(typeof(Customer))
    40                 .SetDateTime("orderDate", orderDate)
    41                 .List<Customer>();
    42         }

    注意这几个方法都是传入的原生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数据库在写查询的时候还是有很多语法上的差别。

  • 相关阅读:
    PHP开发APP接口(三)
    PHP开发APP接口(二)
    PHP开发APP接口(一)
    解密PHP模糊查询技术
    流程的问题
    德邦项目《表》
    微信公众号开发1
    在world2013中插入GB_2312
    HTML5笔记(一)
    蓝色文字显示
  • 原文地址:https://www.cnblogs.com/uncle_danny/p/5678253.html
Copyright © 2011-2022 走看看