nhibernate и "NOT IN" в совокупном подзапросе - PullRequest
1 голос
/ 19 мая 2011

У меня есть объект Напоминание , который содержит коллекцию ReminderSchedule .Это мое отображение:

<class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Reminder" table="Reminders">
    <id name="Code" type="System.Guid">
        <column name="ReminderCode" />
        <generator class="guid.comb" />
    </id>
    ...
    <set access="field.pascalcase-underscore" cascade="all-delete-orphan" inverse="true" lazy="false" name="Schedules" mutable="true">
      <key foreign-key="FK_Schedules_Reminders">
        <column name="ReminderCode" />
      </key>
      <one-to-many class="ReminderSchedule" />
    </set>
</class>

Это отображение для сущности ReminderSchedule :

  <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="ReminderSchedule" table="ReminderSchedules">
    <id name="Code" type="System.Guid">
      <column name="ReminderScheduleCode" />
      <generator class="guid.comb" />
    </id>
    <property name="NextSchedule" type="System.DateTime">
      <column name="NextSchedule" index="ReminderScheduleK01" not-null="true" />
    </property>
    <many-to-one class="Reminder" foreign-key="FK_ReminderScheduleToReminder" name="Reminder">
      <column name="ReminderCode" index="ReminderScheduleK02" not-null="true" />
    </many-to-one>
  </class>

Таблица ReminderSchedules содержит запись для каждого нового сценария, связанного снапоминание.Я могу закрыть расписание (Closed = 1) и перенести новое.
В этой ситуации у меня будут новые записи с Closed = 0, и в поле NextSchedule будет указана дата / время следующего расписания.

Я уже использую CreateCriteria для фильтрации напоминаний, и это работает очень хорошо.Теперь я хотел бы получить напоминания, у которых нет открытого ReminderSchedule.

Я выяснил, как это сделать с помощью запроса:

SELECT * FROM Reminders
WHERE ReminderCode 
    NOT IN (
        SELECT LastReschedule.ReminderCode FROM (
        SELECT ReminderCode, MAX(NextSchedule) MaxSchedule
        FROM ReminderSchedules
        WHERE Closed = 1 
        GROUP BY ReminderCode) LastReschedule
        )
ORDER BY Reminders.ReminderCode

, но я не знаю, как перевести его в критерии, действительные для nhibernate.

Есть ли кто-нибудь, кто может мне помочь?Было бы очень признательно.

Ответы [ 2 ]

2 голосов
/ 23 мая 2011

Поскольку я не смог использовать 2 подзапроса (вложенных), я попытался упростить, используя только один подзапрос.
Я получил идентификатор напоминания (Schedules.Reminder.Code) для закрытых расписаний. К счастью для меня, у меня не должно быть другого графика, если предыдущий не был закрыт. Если это произойдет, слишком плохо, я не смогу справиться с этим.

Это лучшее, что я мог сделать:

ICriteria FiltersCriteria = Session.CreateCriteria<Domain.Reminder>("Reminders");

DetachedCriteria dCriteria = DetachedCriteria.For<Domain.ReminderSchedule>("Schedules")
    .SetProjection(Projections.ProjectionList()
    .Add(Projections.GroupProperty("Schedules.Reminder.Code")))
    // .Add(Projections.Max("Schedules.NextSchedule").As("MaxSchedule")))
    .Add(Restrictions.Eq("Schedules.Closed", true));

FiltersCriteria.Add(Subqueries.PropertyIn("Reminders.Code", dCriteria));  

Полагаю, этот пример кода не требует пояснений.
Я использовал DetachedCriteria для подзапроса, и я использую его как параметр для моих Критерии .

0 голосов
/ 20 мая 2011

Вы можете достичь этого, используя Подзапрос .
в HQL, это должно быть что-то вроде (не проверено):

from Reminders as R
where R.ReminderCode not in
   ( select RS.ReminderCode
     from ReminderSchedules as RS
     where RS.NextSchedule = (select max(NextSchedule) from ReminderSchedules as Inner where RS.Closed = 1)
   )

, даже если я неНе верю, что я нажму точно , что вам нужно, приведенная ссылка должна помочь вам в правильном направлении.

...