Как я могу включить критерий nHibernate против количества совпадающих записей - PullRequest
0 голосов
/ 11 ноября 2011

ПРЕДПОСЫЛКИ:

  • У меня есть таблицы 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.

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

1 Ответ

1 голос
/ 11 ноября 2011

Как и предположил 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, но я не хочу портить вам удовольствие.Этого достаточно, чтобы вы указали в правильном направлении?

...