• 一步步学习NHibernate(9)——连接查询和子查询(1)


    请注明转载地址:http://www.cnblogs.com/arhat

    在前几章中,我们把HQL的基本查询学习了一下,但是只有基本查询很显然不能满足我们的需求,那么就需要一下复杂查询比如”连接查询“,”子查询“等。本章我们就围绕着这两个查询来学习一下。

    现在我们的数据库中只有Student和Clazz两张表,同时这两张表有着多对一和一对多的关系,那么我们就根据这两张表来讲述连接查询吧(当然了,各位网友可以根据自身的情况来学习)。

    在NHibernate中,提供了4中连接查询分别是left outer join ,right outer join,innner join和full join(这个Nhibnerate不推荐使用)。那么下面我们来讲述一下这3个常用的连接查询。

    其实说是链接查询,倒不如说是关联查询,因为在查询的过程中,我们书写的HQL 语句是比较特殊的。大家可以看看下面的案例。

    1,left outer join

    首先我们得弄明白什么是左连接查询,做链接查询是指在查询的时候,把左边表的数据全部查询出来,如果右表的数据和左表数据没有关联的,则右表的数据时使用null来表示。

    string hql = "from Student as t left join t.Clazz";
    
    IList<object[]> list = DAL.NHibernateHelper.CreateQuery(hql, null).List<object[]>();
    
    foreach (object[] objs in list)
     {
    
                    Model.Student student = objs[0] as Model.Student;
    
                    Model.Clazz clazz = objs[1] as Model.Clazz;
    
        Console.WriteLine(student.SName + "-----" + clazz.CName);
    
      }

    从HQL语句中,我们可以看出,在使用链接查询的时候有几个关键点:

    1,需要给对象起个别名

    2,链接的对象是查询对象的属性。

    wps_clip_image-11357

    大家可以从图上看出,NHibernate生成的SQL语句是一个left outer join。但是这是把Student作为左表了,由于Student和Clazz之间一个是多对一的关系,所以Student中的记录是肯定能和Clazz相匹配的,但是我们现在,看看Clazz表和Student中的记录。

    wps_clip_image-24970

    从图上可以看出,Clazz中有一个“SQL Server”这个班级,但是Student中却没有这个班级,所以,如果我们把Clazz作为左表,那么将会是一种什么情况呢,我们来改一下代码,并运行。

    string hql = "from Clazz as t left join t.Students";
    
    IList<object[]> list = DAL.NHibernateHelper.CreateQuery(hql, null).List<object[]>();
    
    foreach (object[] objs in list)
    
    {
    
    Console.WriteLine(objs[0] + "-----" + objs[1]);
    
                }

    wps_clip_image-11361

    从运行结果上看,那么最后一个Model.Clazz对象没有Model.Student对应。我们把上面的代码改写一下,把详细内容显示出来。

    string hql = "from Clazz as t left join t.Students";
    
    IList<object[]> list = DAL.NHibernateHelper.CreateQuery(hql, null).List<object[]>();
    
    foreach (object[] objs in list)
    
                {
    
                    Model.Clazz clazz = objs[0] as Model.Clazz;
    
                    Model.Student student = objs[1] as Model.Student;
    
    if (objs[1] != null)
    
                    {
    
    Console.WriteLine(clazz.CName + "-----" + student.SName);
    
                    }
    
    else
    
                    {
    
    Console.WriteLine(clazz.CName + "-----此班级没有学生"  );
    
                    }
    
                }

    wps_clip_image-2950

    2,right outer join

    那么对于right outer join,老魏在这里不在讲述了,因为它和上面的left outer join 用法是一样的。虽然老魏在这里不再讲述了,那么希望大家能够私下中自行的学习。如果发现有什么问题,可以给老魏留言。

    3,full join

    对于full join由于full join将会产生一个笛卡尔积,而且在实际开发中几乎不会用,所以老魏在这里就不再讲述这个问题了,如果想了解的话可以查看一下NHibernate的帮助文档,NHibernate也不推荐使用的。

    4,inner join

    innner join 对于我们来说可是相当的重要,因为它只把两个表之间的匹配数据查出来,不匹配的则不查询,所以找个非常常用。

    string hql = "from Clazz as t inner  join t.Students";
    
    IList<object[]> list = DAL.NHibernateHelper.CreateQuery(hql, null).List<object[]>();
    
    foreach (object[] objs in list)
    
                {
    
                    Model.Clazz clazz = objs[0] as Model.Clazz;
    
                    Model.Student student = objs[1] as Model.Student;
    
    Console.WriteLine(clazz.CName + "-----" + student.SName);
    
                }

    由于是inner join,所以我们在这里就无需判断对象是否为空了。

    wps_clip_image-19806

    好了,这一章就讲到这里吧,这一章主要是讲述了链接查询,其中的 inner join 是我们最为常用的,所以需要大家能够好好的练习。

  • 相关阅读:
    npm的qs包的使用:stringify()将json对象序列化成表单数据
    git放弃本地某个文件或所有文件的修改
    git关联本地分支和远程分支, 在本地删除远程已经不存在的分支
    vs code代码提示的问题
    js BOM(二)offset系列,scroll系列,client系列,封装变速动画函数
    解决antd design的Modal组件弹出卡顿的问题
    js BOM(一)window、location、history、navigator、定时器setInterval,setTimeout,轮播图
    BizCharts渲染多条曲线时color的使用
    js DOM(三)节点、元素创建3种方式、为元素绑定多个事件addEventListener、attachEvent
    HDU 1081 To The Max
  • 原文地址:https://www.cnblogs.com/arhat/p/3577680.html
Copyright © 2020-2023  润新知