標籤:
摘要
這一篇文章介紹在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.Id22 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)。
NHibernate系列文章二十五:NHibernate查詢之Query Over查詢(附程式下載)