#nhibernate #nhibernate-criteria
#nhibernate #nhibernate-критерии
Вопрос:
СПРАВОЧНАЯ ИНФОРМАЦИЯ:
- У меня есть основные и подробные таблицы, 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 (РАЗНЫЕ РАЗМЕРЫ) = 1»
Но я не уверен, как реализовать это в NHibernate.
Предложения?
Комментарии:
1. Поддерживает ли NH
having
предложение еще? Вы могли бы использовать подзапрос в where like…where 1 = (select count(distinct sizes) from...
Ответ №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
запрос, но я не хочу портить вам удовольствие. Достаточно ли этого, чтобы направить вас в правильном направлении?