Подтвердить что ты не робот

Дизъюнкция 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.

Спасибо.

4b9b3361

Ответ 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;
}