• NHibernate说探——Select,From,Where


    HQL查询

    这里以Northwind数据库为示例数据库

    示例数据表:Employees

    现在只用雇员表中部分字段。

    持久类如下:

    public class Employees

        {

            public virtual int EmployeeID { get; set; }

            public virtual string LastName { get; set; }

            public virtual string FirstName { get; set; }

            public virtual DateTime BirthDate { get; set; }

            public virtual string Address { get; set; }

            public virtual string City { get; set; }

            public virtual string PostalCode { get; set; }

        }

     

    映射文件如下:

    <?xml version="1.0" encoding="utf-8" ?>

    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Domain" namespace="Domain.Entities">

      <class name="Employees" table="Employees">

        <id name="EmployeeID" column="EmployeeID">

          <generator class="identity"></generator>

        </id>

        <property name="LastName" column="LastName" type="String"></property>

        <property name="FirstName" column="FirstName" type="String"></property>

        <property name="BirthDate" column="BirthDate" type="DateTime"></property>

        <property name="Address" column="Address" type="String"></property>

        <property name="City" column="City" type="String"></property>

        <property name="PostalCode" column="PostalCode" type="String"></property>

      </class>

    </hibernate-mapping>

     

    开始

    (一)From

    (1) 返回所有实例(返回所有雇员)

     

    IQuery q = _session.CreateQuery("from Employees");

    return q.List<Employees>();

     

    这种返回的是所有实例,且为持久类型。从哪个映射查询,就返回哪个映射的持久类型。

     

    ·表别名使用

    用法与SQL一样,可以直接在 Employees 后加别名,也可以用as

    IQuery q = _session.CreateQuery("from Employees e");

    IQuery q = _session.CreateQuery("from Employees as e");

    ·面向对象的理解

    从持久类(其实映射的为数据库表Employees表)查询,这里的Employees为持久类,全名为Domain.Entities.Employees

     

    所以,完整的查询应该是:

    IQuery q = _session.CreateQuery("from Domain.Entities.Employees as e");

    return q.List<Employees>();

     

    所以从这里,可以理解为什么这里要区分大小写

    (2)返回部分实例(返回2个雇员)

    IQuery q = _session.CreateQuery("from Employees");

           q.SetMaxResults(2);

    return q.List<Employees>();

    (二)Select

    (1) 返回所有字段的实例

    IQuery q = _session.CreateQuery("select e from Employees e");           

    return q.List<Employees>();

    ·select是构造返回类型的关键字,这里与SQL有些不同。Sql中返回所有字段,可以用*,但这里不可以。须用表别名才可以。

    (2)返回单个字段(城市)

    IQuery q = _session.CreateQuery("select City from Employees");

    return q.List<string>();

     

    ·这里的City要区分大小写。因为这里是做为对象的属性来使用的。其实全名应该为:

    IQuery q = _session.CreateQuery("select e.City from Employees e");

    ·返回的属性是什么类型,则返回的结果应该为相应的类型。查询城市属性,此属性在持久类中为:

    public virtual string City { get; set; }

           所以结果为:q.List<string>()

    (3)返回多字段(城市与名字)

    public IList<Employees> ShowNameCity()

            {

                IQuery q = _session.CreateQuery("select City,FirstName from Employees");

                List<object[]> _objs = q.List<object[]>() as List<object[]>;

     

                IList<Employees> _list = new List<Employees>();

                _list = _objs.ConvertAll<Employees>(new Converter<object[], Employees>(GetEmployees));

     

                return _list;

            }

     

            public Employees GetEmployees(object[] aa)

            {

                return new Employees

                {

                    City = (string)aa[0],

                    FirstName = (string)aa[1]

                };

     }

    这里说明一下,对于返回的多字段这个比较复杂,它返回的是object[] 数组。其实这点也是可以理解的。查询时它找不到与之完全匹配的持久对象,所以返回的是杂项的,可以用多对象多属性来表示这一特征。

    可以用单步分解的方式进行返回结果的包装:

    IList<Employees> _list = new List<Employees>();

                for (int i = 0; i < _objs.Count; i++)

                {

                    _list.Add(new Employees {

                        City = (string)_objs[i][0],

                    FirstName = (string)_objs[i][1]

                    });

         }

    也可以直接对对象进行包装。这里用到了持久类的构造方法。可以这样:

    构造方法:

    public Employees(string strCity, string strFirstName)

            {

                City = strCity;

                FirstName = strFirstName;

     }

     

    查询:

    IQuery q = _session.CreateQuery("select new Employees(City,FirstName) from Employees");

    return q.List<Employees>();

    ·说明一下:构造对象可以随心所欲。可以从新定义一个类(只做为一个实体类型即可),带有相符的属性类型,就可以构造了。

    ·如果用到默认的构造方法,在加参构造后,应该补充默认的构造方法。

    (三) Where(条件)

    (1)查询雇员,以城市为条件

    IQuery q = _session.CreateQuery("from Employees where City=:City")

                                  .SetString("City", strCity);

    return q.List<Employees>();

    ·HQL条件与SQL区别不大

    (2)查询联合的属性

    现在改一下持久类与映射文件。定义雇员的一个新属性:全名。类型为全名类型。(保留原先的属性,只增加新属性)

    public virtual FName FullName { get; set; }

     

    public class FName

              {

                  public string FirstNamee { get; set; }

                  public string LastNamee { get; set; }

                  public string FullName

                  {

                       get

                       {

                            return FirstNamee + "·" + LastNamee;

                       }

                 }

    }

     

    <component name="FullName" class="Domain.Entities.FName,Domain">

                 <property name="FirstNamee" column="FirstName"></property>

                 <property name="LastNamee" column="LastName"></property>

    </component>

     

           查询名字为Nancy的雇员

    IQuery q = _session.CreateQuery("from Employees e where e.FullName.FirstNamee=:FirstNamee")

                    .SetString("FirstNamee", "Nancy");

    return q.List<Employees>();

    这里要说明的就是点语法的复合路径

     

  • 相关阅读:
    ORA-22835:缓冲区对于CLOB到CHAR转换而言太小
    C#发起Http请求,调用接口
    C#发起HTTP请求Post请求
    C# 调用HTTP接口两种方式Demo WebRequest/WebResponse 和WebApi
    SQL中的子查询
    C# 使用multipart form-data方式post数据到服务器
    批处理框架 Spring Batch 这么强,你会用吗
    JAVA基础(一)
    数据库---连接查询多表查询
    数据库---约束
  • 原文地址:https://www.cnblogs.com/jams742003/p/1626266.html
Copyright © 2020-2023  润新知