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

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