Как я могу включить критерий nHibernate для подсчета совпадающих записей

ОБЩАЯ ИНФОРМАЦИЯ:

  • У меня есть таблицы Master и Detail, M и D;
  • M содержит заказы, а D содержит детали заказа с деталями разных размеров (S, M, L, XL).
  • Данный заказ может содержать любое количество частей.
  • 95% всех заказов содержат хотя бы одну вещь размера S
  • Новое требование заключается в том, что размеры могут быть добавлены в будущем, поэтому жесткое кодирование списка для SMLXL больше не работает.

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

Другими словами, вернуть все заказы, содержащие только детали размера S, и исключить все заказы, содержащие смешанные размеры.

Я использовал:

matching_orders.Add(
 Expression.Conjunction()
 .Add(Subqueries.WhereProperty<Orders>(o => o.OrderId).In(DetailQueryOver(S)))
 .Add(Subqueries.WhereProperty<Orders>(o => o.OrderId).NotIn(DetailQueryOver(M)))
 .Add(Subqueries.WhereProperty<Orders>(o => o.OrderId).NotIn(DetailQueryOver(L)))
 .Add(Subqueries.WhereProperty<Orders>(o => o.OrderId).NotIn(DetailQueryOver(XL)))

Должен быть лучший способ. Что-то вроде "где count(DISTINCT SIZES) = 1"

Но я не уверен, как реализовать это в nHibernate.

Предложения?


person Noah    schedule 10.11.2011    source источник
comment
Поддерживает ли NH предложение having? Вы можете использовать подзапрос в том месте, где например...where 1 = (select count(distinct sizes) from...   -  person dotjoe    schedule 11.11.2011


Ответы (1)


Как предложил dotjoe, я полагаю, что предложения having выполняются путем помещения проекции во временную переменную, а затем использования ее как в списке проекций, так и в списке ограничений, хотя я сделал это только с запросами ICriteria, а не QueryOver.

Другой способ написать этот запрос — использовать два подзапроса: один для представления искомого размера, а другой для представления всех остальных размеров. Что-то типа...

select *
from Orders o
where
    exists (
        select d1.Id
        from OrderDetail d1
        where
            d1.Order_id = o.Id
            and d1.Size = @size)
    and not exists (
        select d2.Id
        from OrderDetail d2
        where
            d2.Order_id = o.Id
            and d2.Size <> @size);

Мы могли бы продвинуть этот ответ еще на один шаг вперед и перевести его в запрос QueryOver, но я не хочу портить вам удовольствие. Достаточно ли этого, чтобы указать вам правильное направление?

person Daniel Schilling    schedule 11.11.2011