摘要
这一篇文章介绍在NHibernate 3.2里引入的Query Over查询,Query Over查询跟Criteria查询类似。首先创建IQueryOver对象,然后通过调用该对象的API函数,进行对象查询。这篇文章使用Query Over重写之前所有的查询。
本篇文章的代码可以到NHibernate查询下载
1、创建IQueryOver对象,返回所有Customer信息
1 public IList<Customer> QueryAllOver() 2 { 3 return Session.QueryOver<Customer>().List(); 4 }
2、指定对象,返回数组
1 public IList<int> SelectIdOver() 2 { 3 return Session.QueryOver<Customer>() 4 .List<Customer>().Distinct().Select(c => c.Id).ToList(); 5 }
3、添加查询条件
1 public IList<Customer> GetCustomerByNameOver(string firstName, string lastName) 2 { 3 return Session.QueryOver<Customer>().Where(c => c.FirstName == firstName && c.LastName == lastName).List(); 4 }
另一个模糊查询的例子
1 public IList<Customer> GetCustomersStartWithOver() 2 { 3 //return Session.QueryOver<Customer>().Where(c => c.FirstName.StartsWith("J")).List(); //异常 4 //return Session.QueryOver<Customer>().Where(c => c.FirstName == "J%").List(); //正确 5 //return Session.QueryOver<Customer>().Where(Restrictions.On<Customer>(c => c.FirstName).IsLike("J%")).List(); //正确 6 return Session.QueryOver<Customer>().Where(Restrictions.Like("FirstName", "J%")).List(); 7 }
上面第一句会报异常。使用Query OVer不能在lamda参数里调用所有.net自带类对象的方法,这里调用string类的方法抛出异常。也不能访问NHibernate实体对象的集合属性,例如不能在lamda表达式里访问c.Orders。
return Session.QueryOver<Customer>().Where(c => c.FirstName.StartsWith("J")).List(); //异常
4、order by
1 public IList<Customer> GetCustomersOrderByOver() 2 { 3 return Session.QueryOver<Customer>().OrderBy(c => c.FirstName).Desc().List(); 4 }
对多个字段排序在第一个OrderBy方法调用后,调用ThenBy方法。
5、关联查询
1 public IList<OrderCount> SelectOrderCountOver() 2 { 3 var query = Session.QueryOver<Customer>() 4 .JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders) //关联查询,与Order对象关联,默认是inner join,可以调用重载方法指定join方式 5 .Select(Projections.GroupProperty("Id"), Projections.RowCount()) //分组查询 6 .TransformUsing(Transformers.AliasToBean<OrderCount>()); //将结果投影到OrderCount对象 7 return query.List<OrderCount>(); 8 } 9 10 /// <summary> 11 /// 查询所有订单数量大于2的客户信息 12 /// </summary> 13 /// <returns></returns> 14 public IList<Customer> GetCustomersOrderCountGreaterThanOver() 15 { 16 //分组查询 17 var query = Session.QueryOver<Customer>() 18 .JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders) 19 .Select(Projections.GroupProperty("Id"), Projections.RowCount()); 20 IList<object[]> groups = query.List<object[]>(); 21 //得到订单数大于2的Customer.Id 22 IList<int> ids = groups.Where(g => (int)g[1] > 2).Select(g => (int)g[0]).ToList(); 23 //条件查询 24 return Session.QueryOver<Customer>() 25 .Where(Restrictions.In("Id", ids.ToArray<int>())) 26 .List<Customer>(); 27 } 28 29 /// <summary> 30 /// 查询在指定日期到当前时间内有下订单的客户信息 31 /// </summary> 32 /// <param name="orderDate"></param> 33 /// <returns></returns> 34 public IList<Customer> GetCustomersOrderDateGreatThanOver(DateTime orderDate) 35 { 36 var query = Session.QueryOver<Customer>() 37 .JoinQueryOver<Demo.XML.Entities.Domain.Order>(o => o.Orders) //关联查询 38 .Where(o => o.Ordered > orderDate); //查询条件 39 return query.List<Customer>(); 40 }
结语
NHibernate Query Over跟Criteria类似,不是很灵活,而且API很有限,我们只要理解基本用法就可以了。下篇文章介绍另一个人用得非常多的NHibernate查询:Native Query(SQL Query)。