Дизъюнкция NHibernate приводит к И-запросу вместо OR
Это может быть что-то очевидное, но я уже несколько часов стучаю головой на него и не могу понять, где я ошибаюсь.
Я пытаюсь запустить небольшой фрагмент кода, чтобы проверить добавление критериев OR в запрос NHibernate. Это код, который у меня есть:
using (ISession session = NHibernateHelper.OpenSession())
{
ICriteria criteria = session.CreateCriteria<TestObject>();
int[] ids = {1, 2, 3};
foreach (int id in ids)
{
ICriterion criterion = Restrictions.Eq("Id", id);
criteria.Add(Restrictions.Disjunction().Add(criterion));
}
IList<TestObject> items = criteria.List<TestObject>();
return items;
}
Это просто что-то простое, что я ожидаю вернуть все тестовые объекты с идентификаторами 1-3. Но когда я запускаю код, сгенерированный запрос - это поиск объекта с ID = 1 И ИД = 2 И ИД = 3. Которое, что неудивительно, ничего не возвращает.
Правильно настроено отображение (я могу добавить/отредактировать/удалить/перечислить все объекты), и там есть объекты с этими идентификаторами.
Я делаю что-то явно неправильно? Любые образцы использования Disjunction, которые я видел онлайн, похоже, используют его таким образом. Я просто не понимаю, почему он продолжает использовать AND.
Спасибо.
Ответы
Ответ 1
Ваша проблема заключается в том, что вы каждый раз создаете дизъюнкцию new каждый раз (в цикле). Что вам нужно сделать:
int[] ids = {1, 2, 3};
ICriterion disjunction = Restrictions.Disjunction();
foreach (int id in ids)
{
ICriterion criterion = Restrictions.Eq("Id", id)
disjunction.Add(criterion);
}
criteria.Add(disjunction);
Синтаксис может быть немного неправильным - я парень Hibernate, а не .NET: -)
Чтобы уточнить, ваш исходный код сгенерировал бы что-то вроде (в псевдокоде):
WHERE (OR(ID=1)) AND (OR(ID=2)) AND (OR(ID=3))
Поскольку ничего не "ИЛИ", дизъюнкции молча пропущены.
Ответ 2
Обновлен код на основе ответа ChssPly76:
using (ISession session = NHibernateHelper.OpenSession())
{
ICriteria criteria = session.CreateCriteria<TestObject>();
Junction disjunction = Restrictions.Disjunction();
int[] ids = {1, 2, 3};
foreach (int id in ids)
{
ICriterion criterion = Restrictions.Eq("Id", id);
disjunction.Add(criterion);
}
criteria.Add(disjunction);
IList<TestObject> items = criteria.List<TestObject>();
return items;
}