Я знаю основные способы избежать проблемы выбора N + 1 в Hibernate / NHibernate, но столкнулся с вариантом проблемы, для которого я не могу найти хорошее решение.
У меня сопоставлены следующие три объекта: пункт, категория и клиент. Элемент связан со многими ко многим для Категории, а Категория сопоставлена со многими к одному Клиенту. Пока ничего особенного.
Стандартный запрос в моем приложении - получить все товары для данного клиента. Я делаю это, используя следующие критерии, стараясь с нетерпением извлекать категории элементов, чтобы избежать выбора N + 1 при проверке свойства категорий элементов:
ICriteria criteria = mySession.CreateCriteria(typeof(Item));
.CreateCriteria("Categories", NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(Expression.Eq("Customer", c));
criteria.SetFetchMode("Categories", FetchMode.Eager);
return criteria.List();
Однако это не работает, NHibernate по-прежнему выбирает категории с одним выбором для каждого элемента позже.
Я считаю, что NHibernate знает, что результат первого запроса отфильтрован (для клиента), и что категории, возвращаемые запросом, могут быть неполными, следовательно, позже он должен выполнить отдельный запрос для получить категории. (Это предположение верно? Мне кажется разумным, что NHibernate должен работать таким образом, чтобы обеспечить правильные результаты.)
Однако, согласно моим бизнес-правилам (или как вы хотите их называть), элемент не может принадлежать категориям более чем одного клиента, поэтому в действительности я знаю, что результат первого запроса фактически завершен.
У меня вопрос: могу ли я рассказать NHibernate об этом бизнес-правиле каким-либо образом? Есть ли другой способ избежать выбора N + 1 в такой ситуации (что кажется довольно распространенным)?