• NHibernate3.0剖析:Query篇之NHibernate.Linq标准查询


    系列引入

      NHibernate3.0剖析系列分别从Configuration篇、Mapping篇、Query篇、Session策略篇、应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本。如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧。

      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.zipNHibernate.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接口的Query<T>()扩展方法创建一个NHibernate.Linq查询。

    Linq-Query  首先需要using NHibernate.Linq命名空间,然后使用ISession.Query<T>()获得IQueryable<T>,我们对其做一些延迟操作(例如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的Query<User>(),然后ToList()查询出所有的User对象。

    //Code Snippets Copyright http://lyj.cnblogs.com/
    var basicquery = (from user in session.Query<User>()
    select user).ToList();

    var basicquery2 = session.Query<User>().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.Query<User>()
    where user.Name == "李永京"
    select user).ToList();

    var restrictionquery2 = session.Query<User>().Where(o => o.Name == "李永京").ToList();

      3.投影运算符

    • Select:创建部分序列的投影
    • SelectMany:创建部分序列的一对多投影

      说明:Select运算符对于大多数操作都支持,也支持子查询,但是不支持嵌套Select。SelectMany不支持。

    //Code Snippets Copyright http://lyj.cnblogs.com/
    var selectAnonymousquery = (from user in session.Query<User>()
    select new {user.Name, Age = user.Age}).ToList();

    var selectAnonymousquery2 = session.Query<User>()
    .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.Query<User>()
    select user).Take(2).Skip(2).ToList();

    var partitioningquery2 = session.Query<User>().Take(2).Skip(2).ToList();

      5.排序运算符

    • OrderBy:以升序按值排列序列
    • OrderByDescending:以降序按值排列序列
    • ThenBy:升序排列已排序的序列
    • ThenByDescending:降序排列已排序的序列
    • Reverse:颠倒序列中项目的顺序(用于操作集合)

      说明:排序运算符不支持子查询。

    //Code Snippets Copyright http://lyj.cnblogs.com/
    var orderingquery = (from user in session.Query<User>()
    orderby user.Id descending, user.Name ascending
    select
    user).ToList();

    var orderingquery2 = session.Query<User>()
    .OrderByDescending(o => o.Id).OrderBy(o=>o.Name).ToList();

      6.分组运算符

    • GroupBy:按指定分组方法对序列中的项目进行分组

      例如下面查询:

    //Code Snippets Copyright http://lyj.cnblogs.com/
    var groupquery = (from user in session.Query<User>()
    group user by user.Name
    into g
    select new
    {
    g.Key,
    Age = g.Sum(p => p.Age)
    }).ToList();
    var groupquery2 = session.Query<User>().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.Query<User>().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.Query<User>().First(u => u.Name == "李永京");
    var firstOrDefaultquery = session.Query<User>().FirstOrDefault(u => u.Name == "李永京");

    var singlequery = session.Query<User>().Single(u => u.Name == "李永京");
    var singleOrDefaultquery = session.Query<User>().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.Query<User>().Any();//就是取任意一个

      12.聚合运算符

    • Aggregate:对序列执行一个自定义方法
    • Average:计算数值序列的平均值
    • Count:返回序列中的项目数(整数)
    • LongCount:返回序列中的项目数(长型)
    • Min:查找数字序列中的最小数
    • Max:查找数字序列中的最大数
    • Sum:汇总序列中的数字

      一些简单例子:

    //Code Snippets Copyright http://lyj.cnblogs.com/
    var aggregatequery = session.Query<User>()
    .Where(o => o.Name.Contains("李永京"))
    .Select(o => o.Id)
    .Aggregate(new StringBuilder(), (sb, id) => sb.Append(id).Append(","));
    var average = session.Query<User>().Average(u => u.Age);
    var countquery = session.Query<User>().Count();
    var longCountquery = session.Query<User>().LongCount();
    var minquery = session.Query<User>().Min(u => u.Age);
    var maxquery = session.Query<User>().Max(u => u.Age);
    var sumquery = session.Query<User>().Sum(u => u.Age);

      13.连接运算符

    • Concat:将两个序列连成一个序列

      目前还未支持!

      14.联接运算符

    • GroupJoin:通过归组将两个序列联接在一起
    • Join:将两个序列从内部联接起来

      涉及对象关联操作,以后单独介绍。

      结语

      这篇利用单一对象学习下NHibernate.Linq最基本的标准查询,没有涉及多个对象操作,比较简单,目的让大家先熟悉一下NHibernate.Linq查询。接下来的继续学习NHibernate.Linq。主要有NHibernate.Linq复杂标准查询、NHibernate.Linq增强查询、自定义NHibernate.Linq查询及其在项目中的应用。

      希望本文对你有所帮助。

  • 相关阅读:
    秋色园QBlog技术原理解析:系列终结篇:最后的AOP策略(十九)
    半解TextBox灵异事件背后神秘的深度灵异事件
    SQLite julianday DateTime日期时区问题小记录
    Winform 多组合老板键Alt_Ctrl_Shift
    性能杀手之异常霸气外露!找死!
    DataReader不奇怪,该出手时就出手!
    DBImport v3.0 中文版发布:支持各大数据库数据互导(IT人员必备工具)
    文本数据库.Net界未来的一朵奇葩
    TextBox灵异事件之背后神秘的深度灵异事件真相揭秘
    秋色园QBlog技术原理解析:性能优化篇:读写分离与文本数据库(十八)
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/2418658.html
Copyright © 2020-2023  润新知