Разъединение NHibernate, приводящее к запросам AND вместо OR - PullRequest
12 голосов
/ 26 августа 2009

Это может быть что-то очевидное, но я несколько часов бился об это и не могу понять, где я иду не так.

Я пытаюсь запустить небольшой фрагмент кода, чтобы проверить добавление критериев ИЛИ к запросу 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;
}

Это просто что-то простое, что я ожидаю вернуть все тестовые объекты с ID 1-3. Но когда я запускаю код, сгенерированный запрос состоит в том, чтобы найти объект с ID = 1 И ID = 2 И ID = 3. Что, что неудивительно, ничего не возвращает.

Отображение настроено правильно (я могу добавлять / редактировать / удалять / перечислять все объекты), и там есть объекты с этими идентификаторами.

Я что-то делаю явно неправильно? Любые примеры использования Disjunction, которые я видел в Интернете, похоже, используют его таким образом. Я просто не понимаю, почему он продолжает использовать AND.

Спасибо.

Ответы [ 2 ]

16 голосов
/ 26 августа 2009

Ваша проблема заключается в том, что вы создаете новое дизъюнкция каждый раз (в цикле). Что вам нужно сделать, это:

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))

Поскольку «ИЛИ» ничего не значит, дизъюнкции молча опускаются.

5 голосов
/ 26 августа 2009

Обновлен код, основанный на ответе 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...