NHibernate3.0剖析系列分别从Configuration篇、Mapping篇、Query篇、Session策略篇、应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成基于NHibernte3.0版本。如果你还不熟悉NHibernate可以快速阅读NHibernate之旅系列文章导航系列入门如果你已经在用NHibernate了那么请跟上NHibernate3.0剖析系列吧。NHibernate专题http://kb.cnblogs.com/zt/nhibernate/NHibernate官方站点http://nhforge.org/NHibernate参考文档http://nhforge.org/doc/nh/en/获取NHibernate地址http://sourceforge.net/projects/nhibernate/NHibernate.Linq概述NHibernate.Linq基于HQL AST分析器的Linq Provider由Steve Strong贡献者开发的底层使用第三方Re-Linq开源框架。所以NHibernate3.0多了一个必需程序集Remotion.Data.Linq.dll。注意在之前NHibernate版本中并不存在Linq功能 Ayende Rahien贡献者为NHibernate2.1.0GA和NHibernate2.1.2GA版本设计第三方NHiberante.Linq.dll(对应为 NHibernate.Linq-1.0.0.GA-bin.zip和 NHibernate.Linq-2.1.2-GA-Bin.zip)(目前已经停止了维护)它是基于Criteria API的Linq Provider主要功能是将简单的Linq表达式转化为Criteria API由于Criteria API的功能有限所以存在很多天生的不足(联接和子查询不支持)。如果使用NHibernate2.1.0GA或者NHibernate2.1.2GA版本可以下载使用NHiberante.Linq.dll在这里不作介绍。下面看看NHibernate提供的全新的NHibernate.Linq查询。我们使用ISession接口的QueryT()扩展方法创建一个NHibernate.Linq查询。首先需要using NHibernate.Linq命名空间然后使用ISession.QueryT()获得IQueryableT我们对其做一些延迟操作(例如where、orderby等)最后使用不延迟的操作(例如ToList()、Count()、FirstOrDefault())返回需要的结果。注意NHibernate.Linq查询将Linq运算符转换为HQL有些Linq运算符本身是专门处理集合的而SQL主要是在处理无序值集。所以NHibernate.Linq查询肯定不需要支持这些专门处理集合的运算符例如Except、Intersect、转换运算符、生成运算符等。下面列举所有Linq运算符和说明并列举了一些简单的NHibernate.Linq查询我仅仅对单一对象User对象操作//Code Snippets Copyright http://lyj.cnblogs.com/ public class User { public Guid Id { get; set; } public string Name { get; set; } public int Age { get; set; } }标准查询运算符1.基本形式使用ISession的QueryUser()然后ToList()查询出所有的User对象。//Code Snippets Copyright http://lyj.cnblogs.com/ var basicquery (from user in session.QueryUser() select user).ToList(); var basicquery2 session.QueryUser().ToList();2.限制运算符Where筛选序列中的项目说明对属性值一些筛选筛选属性支持组件、枚举、各种关联、支持基本类型的方法。例如Int等类型的等于、大于、小于不等于String类型的StartsWith、EndsWith、Contains、Equals、ToLower、ToLowerInvariant、ToUpper、ToUpperInvariant、Substring、IndexOf等DateTime的Year、Date、Month等。也可以在Where运算符中使用聚合操作符的子查询。//Code Snippets Copyright http://lyj.cnblogs.com/ var restrictionquery (from user in session.QueryUser() where user.Name 李永京 select user).ToList(); var restrictionquery2 session.QueryUser().Where(o o.Name 李永京).ToList();3.投影运算符Select创建部分序列的投影SelectMany创建部分序列的一对多投影说明Select运算符对于大多数操作都支持也支持子查询但是不支持嵌套Select。SelectMany不支持。//Code Snippets Copyright http://lyj.cnblogs.com/ var selectAnonymousquery (from user in session.QueryUser() select new {user.Name, Age user.Age}).ToList(); var selectAnonymousquery2 session.QueryUser() .Select(o new {o.Name, Age o.Age}) .ToList();4.分区运算符Skip返回跳过指定数目项目的序列SkipWhile返回跳过不满足表达式项目的序列Take返回具有指定数目项目的序列TakeWhile返回具有满足表达式项目的序列说明不支持SkipWhile和TakeWhile。不支持连写多个Take或者Skip。//Code Snippets Copyright http://lyj.cnblogs.com/ var partitioningquery (from user in session.QueryUser() select user).Take(2).Skip(2).ToList(); var partitioningquery2 session.QueryUser().Take(2).Skip(2).ToList();5.排序运算符OrderBy以升序按值排列序列OrderByDescending以降序按值排列序列ThenBy升序排列已排序的序列ThenByDescending降序排列已排序的序列Reverse颠倒序列中项目的顺序(用于操作集合)说明排序运算符不支持子查询。//Code Snippets Copyright http://lyj.cnblogs.com/ var orderingquery (from user in session.QueryUser() orderby user.Id descending, user.Name ascending select user).ToList(); var orderingquery2 session.QueryUser() .OrderByDescending(o o.Id).OrderBy(oo.Name).ToList();6.分组运算符GroupBy按指定分组方法对序列中的项目进行分组例如下面查询//Code Snippets Copyright http://lyj.cnblogs.com/ var groupquery (from user in session.QueryUser() group user by user.Name into g select new { g.Key, Age g.Sum(p p.Age) }).ToList(); var groupquery2 session.QueryUser().GroupBy(o o.Name) .Select(o new { o.Key, Age o.Sum(p p.Age)}).ToList();7.设置运算符Distinct返回无重复项目的序列Except返回代表两个序列差集的序列(用于操作集合)Intersect返回代表两个序列交集的序列(用于操作集合)Union返回代表两个序列交集的序列(用于操作集合)目前支持Distinct//Code Snippets Copyright http://lyj.cnblogs.com/ var distinctquery session.QueryUser().Distinct().ToList();8.转换运算符(用于操作集合)Cast将序列中的元素转换成指定类型OfType筛选序列中指定类型的元素ToArray从序列返回一个数组ToDictionary从序列返回一个字典ToList从序列返回一个列表ToLookup从序列返回一个查询ToSequence返回一个IEnumerable序列NHibernate.Linq不需要支持。9.元素运算符DefaultIfEmpty为空序列创建默认元素(用于操作集合)ElementAt返回序列中指定索引的元素(用于操作集合)ElementAtOrDefault返回序列中指定索引的元素或者如果索引超出范围则返回默认值(用于操作集合)First返回序列中的第一个元素FirstOrDefault返回序列中的第一个元素或者如果未找到元素则返回默认值Last返回序列中的最后一个元素(用于操作集合)LastOrDefault返回序列中的最后一个元素或者如果未找到元素则返回默认值(用于操作集合)Single返回序列中的单个元素SingleOrDefault返回序列中的单个元素或者如果未找到元素则返回默认值例如下面例子//Code Snippets Copyright http://lyj.cnblogs.com/ var firstquery session.QueryUser().First(u u.Name 李永京); var firstOrDefaultquery session.QueryUser().FirstOrDefault(u u.Name 李永京); var singlequery session.QueryUser().Single(u u.Name 李永京); var singleOrDefaultquery session.QueryUser().SingleOrDefault(u u.Name 李永京);10.生成运算符(用于操作集合)Empty生成一个空序列Range生成一个指定范围的序列Repeat通过将某个项目重复指定次数来生成一个序列NHibernate.Linq不需要支持。11.限定符All确定序列中的所有项目是否满足某个条件Any确定序列中是否有任何项目满足条件Contains确定序列是否包含指定项目仅写下Any示例//Code Snippets Copyright http://lyj.cnblogs.com/ var anyquery session.QueryUser().Any();//就是取任意一个