zoukankan      html  css  js  c++  java
  • NHibernate 数据查询之Linto to NHibernate (第八篇)

      刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术 相关联,只有NHibernate用到,一来容易忘记,二来没有智能提示,排除错误什么的都不给力,直到看到一个同事用Linq to NHibernate,那代码是相当的清晰明了,其实什么条件查询,HQL什么的感觉只是一个NHibernate用到,很容易忘记。而SQL跟Linq 是经常用的东西,还是SQL和Linq比较划算。今天就来写下Linq to NHibernate。

      引用NHibernate.Linq后,创建查询时应该这样

      session.Query<Person_Model>()...

      而不是

      session.QueryOver<Person_Model>().AndNot(m => m.State).List();

      以下运算符据说是在NHibernate.Linq命名空间里的,但是本人下载的默认NHibernate找不到,先列出所有的操作符,供以后可以查找

      一、限制运算符

    Where:筛选序列中的项目
    WhereNot:反筛选序列中的项目

      二、投影运算符

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

    三、分区运算符(分页常用到)

    Skip:返回跳过指定数目项目的序列
    SkipWhile:返回跳过不满足表达式项目的序列
    Take:返回具有指定数目项目的序列
    TakeWhile:返回具有满足表达式项目的序列

    四、排序运算符

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

    五、分组运算符

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

    六、设置运算符

    Distinct:返回无重复项目的序列
    Except:返回代表两个序列差集的序列(用于操作集合)
    Intersect:返回代表两个序列交集的序列(用于操作集合)
    Union:返回代表两个序列交集的序列(用于操作集合)

    七、转换运算符

    Cast:将序列中的元素转换成指定类型
    OfType:筛选序列中指定类型的元素
    ToArray:从序列返回一个数组
    ToDictionary:从序列返回一个字典
    ToList:从序列返回一个列表
    ToLookup:从序列返回一个查询
    ToSequence:返回一个IEnumerable序列

    八、元素运算符

    DefaultIfEmpty:为空序列创建默认元素(用于操作集合)
    ElementAt:返回序列中指定索引的元素(用于操作集合)
    ElementAtOrDefault:返回序列中指定索引的元素,或者如果索引超出范围,则返回默认值(用于操作集合)
    First:返回序列中的第一个元素
    FirstOrDefault:返回序列中的第一个元素,或者如果未找到元素,则返回默认值
    Last:返回序列中的最后一个元素(用于操作集合)
    LastOrDefault:返回序列中的最后一个元素,或者如果未找到元素,则返回默认值(用于操作集合)
    Single:返回序列中的单个元素
    SingleOrDefault:返回序列中的单个元素,或者如果未找到元素,则返回默认值

    九、生成运算符

    Empty:生成一个空序列
    Range:生成一个指定范围的序列
    Repeat:通过将某个项目重复指定次数来生成一个序列

    十、限定符

    All:确定序列中的所有项目是否满足某个条件
    Any:确定序列中是否有任何项目满足条件
    Contains:确定序列是否包含指定项目

    十一、聚合运算符

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

    十二、连接运算符

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

    十三、联接运算符

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

      我新建了一个张表,并添加了十几条数据。

      在NHibernate中,linq查询通过session.QueryOver<T>()创建。我们先来看看NHibernate本身自带的Linq提供的操作符。

      1、And

    public IList<Person_Model> Select()
    {
      IList<Person_Model> list = session.QueryOver<Person_Model>().And(m => m.State).List();  //查询所有state字段为True的记录
      NHibernateHelper.CloseSession();  
      return list;
    }

        以上生成的SQL语句为

    exec sp_executesql N'SELECT this_.Id as Id1_0_, this_.name as name1_0_, this_.age as age1_0_, this_.state as state1_0_ FROM Person this_ WHERE this_.state = @p0',N'@p0 bit',@p0=1

      可以看到And实际上相当于一条Where语句了。条件为True的返回。

      我们把And换成Where再来看看生成的SQL语句。

    exec sp_executesql N'SELECT this_.Id as Id1_0_, this_.name as name1_0_, this_.age as age1_0_, this_.state as state1_0_ FROM Person this_ WHERE this_.state = @p0',N'@p0 bit',@p0=1

      呵呵,没有区别。留待

      2、AndNot

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().AndNot(m => m.State).List();  //查询所有state字段等于false的记录
                NHibernateHelper.CloseSession();
                return list;
            }

      我们来看看生成的SQL语句

    exec sp_executesql N'SELECT this_.Id as Id1_0_, this_.name as name1_0_, this_.age as age1_0_, this_.state as state1_0_ FROM Person this_ WHERE not (this_.state = @p0)',N'@p0 bit',@p0=1

      留意到它只比And操作符的区别在于在where条件后加了个not()

      3、AndRestrictionOn

      AndRestrictionOn的中文意思是,添加限制条件。

    复制代码
            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().AndRestrictionOn(m => m.Name).IsLike("",NHibernate.Criterion.MatchMode.Anywhere).List();
                NHibernateHelper.CloseSession();
                return list;
            }
    复制代码

      第二个参数IsLike的第二个参数NHibernate.Criterion.MatchMode.Anywhere是一个枚举,指示百分号应该添加到哪里?

      生成的SQL语句如下:

    exec sp_executesql N'SELECT this_.Id as Id1_0_, this_.name as name1_0_, this_.age as age1_0_, this_.state as state1_0_ FROM Person this_ WHERE this_.name like @p0',N'@p0 nvarchar(4000)',@p0=N'%诸%'

       4、JoinAlias

        JoinAlias主要用于连接表并添加别名,对应的SQL字句是Join,根据Person查Country

    复制代码
            public IList<Person_Model> Select()
            {
                Country_Model country = null;   //必须定义一个用于别名的Country_Model,且必须为null
                IList<Person_Model> list = session.QueryOver<Person_Model>().JoinAlias(m => m.Country, () => country).List();
                NHibernateHelper.CloseSession();
                return list;
            }
    复制代码

        生成的sql语句为

    SELECT this_.Id as Id0_1_, this_.name as name0_1_, this_.age as age0_1_, this_.state as state0_1_, this_.CountryId as CountryId0_1_, country1_.CountryId as CountryId1_0_, country1_.CountryName as CountryN2_1_0_ FROM Person this_ inner join Country country1_ on this_.CountryId=country1_.CountryId

        该查询会把Country的信息也查出来。

        其次,JoinAlias还可以支持第三个参数,其用于指定外连接的类型。

        例如将JoinAlias改为:

    复制代码
            public IList<Person_Model> Select()
            {
                Country_Model country = null;   //必须定义一个用于别名的Country_Model,且必须为null
                IList<Person_Model> list = session.QueryOver<Person_Model>().JoinAlias(m => m.Country, () => country,NHibernate.SqlCommand.JoinType.LeftOuterJoin).List();
                NHibernateHelper.CloseSession();
                return list;
            }
    复制代码

        则,生成的SQL语句为:

    SELECT this_.Id as Id0_1_, this_.name as name0_1_, this_.age as age0_1_, this_.state as state0_1_, this_.CountryId as CountryId0_1_, country1_.CountryId as CountryId1_0_, country1_.CountryName as CountryN2_1_0_ FROM Person this_ left outer join Country country1_ on this_.CountryId=country1_.CountryId

        NHibernate.SqlCommand.JoinType是一个枚举类型,其支持的值有

        枚举值            对应的SQL

        FullJoin            full outer join

        InnerJoin           inner join

        LeftOuterJoin         left outer join

        RightOuterJoin         right outer join

        None              不连接,不连接还要这个参数干嘛?

        5、JoinQueryOver

    复制代码
            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().OrderBy(p => p.Age).Desc.Inner.JoinQueryOver<Country_Model>(o => o.Country).List();
                NHibernateHelper.CloseSession();   
                return list;
            }
    复制代码

        生成的SQL语句为

    SELECT this_.Id as Id0_1_, this_.name as name0_1_, this_.age as age0_1_, this_.state as state0_1_, this_.CountryId as CountryId0_1_, country_mo1_.CountryId as CountryId1_0_, country_mo1_.CountryName as CountryN2_1_0_ FROM Person this_ inner join Country country_mo1_ on this_.CountryId=country_mo1_.CountryId ORDER BY this_.age desc

        JoinQueryOver与JoinAlias只有返回不同,返回不同就可以继续衔接。比如:

      NHH.GetSession().QueryOver<Permission>().JoinQueryOver<Role>(m => m.Roles, () => role).JoinQueryOver<User>(m => m.Users, () => user).Where(m => m.Account == Account).List<Permission>();

      在多表Join的情况下,你条查询条件从Permission => Roles => User。如果用JoinAlias就一直是对表Permission操作,没有办法转到User。

        6、OrderBy

        Order主要用于排序,相当于SQL语句里面的order by。

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().OrderBy(p => p.Age).Desc.List();   //按照年龄降序排序
                NHibernateHelper.CloseSession();   
                return list;
            }

        生成的SQL语句为

    SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ ORDER BY this_.age desc

        其中OrderBy方法后面能跟的属性有两个,分别是Asc与Desc与数据库的SQL语句对应相同意思。

        7、OrderByAlias

        8、Lock

         9、Select

        告知NHibernate你想要查询的是什么东西。

                IList<int> list1 = session.QueryOver<Person_Model>().Select(p => p.Age).List<int>();  //获取所有年龄的IList集合
                NHibernateHelper.CloseSession();   
                return list;

        生成的SQL语句为

            SELECT this_.age as y0_ FROM Person this_

        10、ThenBy

        与SQL语句中的then by同义。

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().OrderBy(p => p.Age).Asc.ThenBy(p => p.Id).Desc.List();
                NHibernateHelper.CloseSession();   
                return list;
            }

         生成的SQL语句为

      SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ ORDER BY this_.age asc, this_.Id desc

        11、Where

          添加where条件,与SQL语句同义。

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().Where(p => p.Age > 50).List();
                NHibernateHelper.CloseSession();   
                return list;
            }

          生成的SQL语句为

    exec sp_executesql N'SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ WHERE this_.age > @p0',N'@p0 int',@p0=50

        12、WhereNot

          添加where条件,只是前面加了个Not。

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().WhereNot(p => p.Age > 50).List();
                NHibernateHelper.CloseSession();   
                return list;
            }

          生成的SQL语句为

    exec sp_executesql N'SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ WHERE not (this_.age > @p0)',N'@p0 int',@p0=50

        13、Skip

          跳过指定数量的记录

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().Skip(5).List();
                NHibernateHelper.CloseSession();   
                return list;
            }

          生成的SQL语句为

    exec sp_executesql N'SELECT TOP (2147483647) Id0_0_, name0_0_, age0_0_, state0_0_, CountryId0_0_ FROM (SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_, ROW_NUMBER() OVER(ORDER BY CURRENT_TIMESTAMP) as __hibernate_sort_row FROM Person this_) as query WHERE query.__hibernate_sort_row > @p0 ORDER BY query.__hibernate_sort_row',N'@p0 int',@p0=5

        14、Take

          获取指定数量的记录,与Skip配合使用是经常用到的分页效果。

            public IList<Person_Model> Select()
            {
                IList<Person_Model> list = session.QueryOver<Person_Model>().Take(5).List();
                NHibernateHelper.CloseSession();   
                return list;
            }

          生成的SQL语句为

    exec sp_executesql N'SELECT TOP (@p0)  this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_',N'@p0 int',@p0=5

        15、RowCount()

          统计符合条件的记录,相当于Select Count(*) from...

                int count = session.QueryOver<Person_Model>().RowCount();
                NHibernateHelper.CloseSession(); 

          生成的SQL语句为

        SELECT count(*) as y0_ FROM Person this_

        16、RowCountInt64

          也是统计记录,与RowCount没什么区别,只是返回的记录是long类型的。

                long count = session.QueryOver<Person_Model>().RowCountInt64();
                NHibernateHelper.CloseSession();   

           生成的SQL语句为

      SELECT count(*) as y0_ FROM Person this_

        17、SingleOrDefault

           返回符合条件的第一条记录,当为空是,返回一个各属性为null的对应类型的对象。

                Person_Model p = session.QueryOver<Person_Model>().Where(m => m.Age == 10).SingleOrDefault();
                NHibernateHelper.CloseSession();   

          生成的SQL语句为

    exec sp_executesql N'SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ WHERE this_.age = @p0',N'@p0 int',@p0=10

        18、Future

          Future()与List()的区别在于Future返回的是IEnumerable<>集合,而List()返回的是IList()。

                IEnumerable<Person_Model> list1 = session.QueryOver<Person_Model>().Where(m => m.Age > 10).Future();
                NHibernateHelper.CloseSession();   

          与SQL语句无关

        19、List

          List()将结果集合封装为IList()接口集合返回。

                IList<Person_Model> list = session.QueryOver<Person_Model>().WhereRestrictionOn(p => p.Age).IsIn(ints).List();
                NHibernateHelper.CloseSession();   

          与SQL语句无关。

        20、FutureValue()

                IFutureValue<Person_Model> list1 = session.QueryOver<Person_Model>().WhereRestrictionOn(p => p.Age).IsIn(ints).FutureValue();
                Person_Model p1 = list1.Value;

          FutureValue()这是一个非常简单的接口,里面就一个泛型的Value属性,也就是说.FutureValue()这个东西只是装载了一个对应查询类型的对象而已。

          与SQL语句无关。

        21、WhereRestrictionOn

          这个东西与前面说的AdnRestrictionOn是一样的,也是可以添加条件啥乱七八糟的。

                IEnumerable<Person_Model> list1 = session.QueryOver<Person_Model>().WhereRestrictionOn(p => p.Age).IsIn(ints).Future();
                NHibernateHelper.CloseSession();   

          生成的SQL代码为:

    exec sp_executesql N'SELECT this_.Id as Id0_0_, this_.name as name0_0_, this_.age as age0_0_, this_.state as state0_0_, this_.CountryId as CountryId0_0_ FROM Person this_ WHERE this_.age in (@p0, @p1, @p2)',N'@p0 int,@p1 int,@p2 int',@p0=20,@p1=25,@p2=31
  • 相关阅读:
    C++ 11 lambda
    Win环境下的文件读写
    基于 Jenkins+Docker+Git 的CI流程初探
    python切片操作
    k8s 集群中的etcd故障解决
    Git 版本控制管理(二)
    Git 版本控制管理(一)
    Harbor 企业级镜像仓库搭建
    docker 数据管理
    docker 网络的几种模式
  • 原文地址:https://www.cnblogs.com/liuguanghai/p/5031909.html
Copyright © 2011-2022 走看看