Выберите последнюю группу в nhibernate - PullRequest
0 голосов
/ 15 июня 2010

В моем приложении есть объекты Canine и CanineHandler.У объекта CanineHandler есть PersonID (который ссылается на совершенно другую базу данных), EffectiveDate (который указывает, когда обработчик запускается с собакой) и ссылка FK на Canine (CanineID).

С учетом определенного 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 из: OPS.CanineApp.Model.Canine».Очевидно, что я что-то упустил (а), но из документации у меня сложилось впечатление, что следует вернуть список клыков, имеющих обработчики (возможно, с дубликатами).Пока я не смогу выполнить эту работу, добавление подзапроса работать не будет ...

Я нашел похожие вопросы, такие как Получать только последние результаты, используя nHibernate , но ни один изкажется, что ответы действительно применимы к тому прямому результату, который я ищу.

Любая помощь или предложение приветствуются.

1 Ответ

1 голос
/ 23 июня 2010

Присоединение к производной таблице, 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>();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...