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

时间:2023-12-12 11:39:56

摘要

这一篇文章介绍在NHibernate 3.2里引入的Query Over查询,Query Over查询跟Criteria查询类似。首先创建IQueryOver对象,然后通过调用该对象的API函数,进行对象查询。这篇文章使用Query Over重写之前所有的查询。

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

1、创建IQueryOver对象,返回所有Customer信息

         public IList<Customer> QueryAllOver()
{
return Session.QueryOver<Customer>().List();
}

2、指定对象,返回数组

         public IList<int> SelectIdOver()
{
return Session.QueryOver<Customer>()
.List<Customer>().Distinct().Select(c => c.Id).ToList();
}

3、添加查询条件

         public IList<Customer> GetCustomerByNameOver(string firstName, string lastName)
{
return Session.QueryOver<Customer>().Where(c => c.FirstName == firstName && c.LastName == lastName).List();
}

另一个模糊查询的例子

         public IList<Customer> GetCustomersStartWithOver()
{
//return Session.QueryOver<Customer>().Where(c => c.FirstName.StartsWith("J")).List(); //异常
//return Session.QueryOver<Customer>().Where(c => c.FirstName == "J%").List(); //正确
//return Session.QueryOver<Customer>().Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("J%")).List(); //正确
return Session.QueryOver<Customer>().Where(Restrictions.Like("FirstName", "J%")).List();
}

上面第一句会报异常。使用Query OVer不能在lamda参数里调用所有.net自带类对象的方法,这里调用string类的方法抛出异常。也不能访问NHibernate实体对象的集合属性,例如不能在lamda表达式里访问c.Orders。

return Session.QueryOver<Customer>().Where(c => c.FirstName.StartsWith("J")).List();  //异常

4、order by

         public IList<Customer> GetCustomersOrderByOver()
{
return Session.QueryOver<Customer>().OrderBy(c => c.FirstName).Desc().List();
}

对多个字段排序在第一个OrderBy方法调用后,调用ThenBy方法。

5、关联查询

         public IList<OrderCount> SelectOrderCountOver()
{
var query = Session.QueryOver<Customer>()
.JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders) //关联查询,与Order对象关联,默认是inner join,可以调用重载方法指定join方式
.Select(Projections.GroupProperty("Id"), Projections.RowCount()) //分组查询
.TransformUsing(Transformers.AliasToBean<OrderCount>()); //将结果投影到OrderCount对象
return query.List<OrderCount>();
} /// <summary>
/// 查询所有订单数量大于2的客户信息
/// </summary>
/// <returns></returns>
public IList<Customer> GetCustomersOrderCountGreaterThanOver()
{
//分组查询
var query = Session.QueryOver<Customer>()
.JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders)
.Select(Projections.GroupProperty("Id"), Projections.RowCount());
IList<object[]> groups = query.List<object[]>();
//得到订单数大于2的Customer.Id
IList<int> ids = groups.Where(g => (int)g[] > ).Select(g => (int)g[]).ToList();
//条件查询
return Session.QueryOver<Customer>()
.Where(Restrictions.In("Id", ids.ToArray<int>()))
.List<Customer>();
} /// <summary>
/// 查询在指定日期到当前时间内有下订单的客户信息
/// </summary>
/// <param name="orderDate"></param>
/// <returns></returns>
public IList<Customer> GetCustomersOrderDateGreatThanOver(DateTime orderDate)
{
var query = Session.QueryOver<Customer>()
.JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders) //关联查询
.Where(o => o.Ordered > orderDate); //查询条件
return query.List<Customer>();
}

结语

NHibernate Query Over跟Criteria类似,不是很灵活,而且API很有限,我们只要理解基本用法就可以了。下篇文章介绍另一个人用得非常多的NHibernate查询:Native Query(SQL Query)。