使用NHibernate和Native SQL从表中选择几列

时间:2016-09-09 00:35:50

标签: c# .net nhibernate orm

我正在使用C#语言使用NHibernate开发一个Web应用程序。但是,我无法使用少量字段构建本机MySQL查询,然后进行映射。

我的 hbm.xml 如下所示:

  <class name="Rule" table="rule">
    <id name="Id" column="id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="Name" column="name" type="String" not-null="false"></property>
    <property name="Description" column="description" type="String" not-null="false"></property>
    <property name="Shops" column="shops" type="String" not-null="false"></property>
    <property name="Channels" column="channels" type="String" not-null="false"></property>
    <property name="Currency" column="currency" type="int" not-null="false"></property>
    <property name="Range" column="range" type="int" not-null="false"></property>
    <property name="Created" column="created" type="DateTime" ></property>
    <property name="Modified" column="modified" type="DateTime" ></property>
  </class>

我的原生查询如下:

 var session = this.GetFactory().OpenSession();
            var query = session.CreateSQLQuery("SELECT * FROM `rule` WHERE currency = :currency AND `range` = :range");
            query.SetParameter("currency", this.SearchRoot.Currency.Id);
            query.SetParameter("range", this.SearchRoot.Range.Id);
            query.AddEntity(typeof(Rule));

            var rules = query.List<Rule>();

当我运行我的应用程序时,一切都很好。但是对于这个特殊情况,我不需要所有我只需要ID,商店和频道的字段,所以我做了以下更改:

 var session = this.GetFactory().OpenSession();
            var query = session.CreateSQLQuery("SELECT id, shops, channels FROM `rule` WHERE currency = :currency AND `range` = :range");
            query.SetParameter("currency", this.SearchRoot.Currency.Id);
            query.SetParameter("range", this.SearchRoot.Range.Id);
            query.AddEntity(typeof(Rule));

            var rules = query.List<Rule>();

然后我收到以下错误:

异常详细信息:System.IndexOutOfRangeException:在结果中找不到指定的列:name

据我所知,NHibernate总是尝试将类属性与表的字段匹配。我阅读了有关原生查询的文档。

nhibernate native query

但我无法找到与此特定案例相关的任何样本或内容。

任何帮助?

1 个答案:

答案 0 :(得分:1)

这非常容易:

  1. 执行使用AddEntity(typeof(MyEntity)
  2. 使用 Transformer Transformers.AliasToBean<MyEntity>()
  3. 但是,现在我们必须更改SQL SELECT语句:

      

    列别名必须与属性名称

    匹配

    起草的解决方案:

    var query = session.CreateSQLQuery("SELECT id as ID, shops as Shop ....");
    ...
    //query.AddEntity(typeof(Rule));
    query.SetResultTransformer(Transformers.AliasToBean<Rule>())
    

    摘要......如果我们提供在映射中定义的所有列,我们可以直接映射到实体。匹配由列名称和 column="" 映射驱动。我们也可以使用projectin,只选择几列...在这种情况下,我们必须提供等于 name="" 映射的别名并使用Transformer(我们甚至可以使用more complex projection