在nhibernate中选择最新的组

时间:2010-06-15 18:34:41

标签: c# nhibernate

我的应用程序中有Canine和CanineHandler对象。 CanineHandler对象有一个PersonID(引用一个完全不同的数据库),一个EffectiveDate(指定处理程序何时以犬开始)和一个对Canine(CanineID)的FK引用。

鉴于具体的PersonID,我想找到他们目前负责的所有犬科动物。我在SQL中使用的(简化)查询将是:

Select Canine.*
    from Canine
        inner join CanineHandler on(CanineHandler.CanineID=Canine.CanineID)
        inner join 
            (select CanineID,Max(EffectiveDate) MaxEffectiveDate
                from caninehandler
                group by CanineID) as CurrentHandler
            on(CurrentHandler.CanineID=CanineHandler.CanineID
                and CurrentHandler.MaxEffectiveDate=CanineHandler.EffectiveDate)
    where CanineHandler.HandlerPersonID=@PersonID

编辑:在下面添加了映射文件:

<class name="CanineHandler" table="CanineHandler" schema="dbo">
    <id name="CanineHandlerID" type="Int32">
        <generator class="identity" />
    </id>
    <property name="EffectiveDate" type="DateTime" precision="16" not-null="true" />
    <property name="HandlerPersonID" type="Int64" precision="19" not-null="true" />
    <many-to-one name="Canine" class="Canine" column="CanineID" not-null="true" access="field.camelcase-underscore" />
</class>

<class name="Canine" table="Canine">
    <id name="CanineID" type="Int32">
        <generator class="identity" />
    </id>
    <property name="Name" type="String" length="64" not-null="true" />
    ...
    <set name="CanineHandlers" table="CanineHandler" inverse="true" order-by="EffectiveDate desc" cascade="save-update" access="field.camelcase-underscore">
        <key column="CanineID" />
        <one-to-many class="CanineHandler" />
    </set>
    <property name="IsDeleted" type="Boolean" not-null="true" />
</class>

我还没有尝试过,但我猜我可以在HQL中做到这一点。我还没有在HQL中编写任何东西,所以无论如何我最终都必须解决这个问题,但我的问题是我是否/如何使用标准/子查询对象来执行此子查询。

我创建了以下分离标准:

DetachedCriteria effectiveHandlers = DetachedCriteria.For<Canine>()
                .SetProjection(Projections.ProjectionList()
                    .Add(Projections.Max("EffectiveDate"),"MaxEffectiveDate")
                    .Add(Projections.GroupProperty("CanineID"),"handledCanineID")
                );

但我无法弄清楚如何进行内连接。如果我这样做:

Session.CreateCriteria<Canine>()
    .CreateCriteria("CanineHandler", "handler", NHibernate.SqlCommand.JoinType.InnerJoin)
    .List<Canine>();

我收到错误“无法解析属性:CanineHandler of:OPS.CanineApp.Model.Canine”。显然我错过了一些东西但是从文档中我得到的印象应该是返回一个带有处理程序的犬类列表(可能有重复项)。在我完成这项工作之前,添加子查询是行不通的......

我发现了类似的问题,例如Only get latest results using nHibernate,但没有一个答案真正适用于我正在寻找的那种直接结果。

非常感谢任何帮助或建议。

1 个答案:

答案 0 :(得分:1)

在我上次检查时,加入到派生表中的示例中的CurrentHandler将无法在HQL中运行。尝试映射存储过程,该过程允许您编写任何您喜欢的SQL。这是映射存储过程的样子:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="S2.BP.NHSupport" namespace="S2.BP.Model">
  <sql-query name="spGoGetMyDogs" callable="true">
    <return-scalar column="PersonID" type="int" />
    exec spGoGetMyDogs @PersonID=:personID
  </sql-query>
</hibernate-mapping>

然后你可以传递你的PersonID参数并让NH使用变换器将结果映射回你的对象:

public IEnumerable<Canine> LetTheDogsOut(int personID) {
  return nhSession.GetNamedQuery("spGoGetMyDogs")
    .SetInt32("personID", personID)
    .SetResultTransformer(Transformers.AliasToBean(typeof(Canine)))
    .List<Canine>();
}