Nhibernate QueryOver Field1 = True ИЛИ (Коллекция содержит ...) - PullRequest
1 голос
/ 19 сентября 2011

Я пишу обработчик для формы поиска.У искомого объекта есть 3 логических флага и несколько коллекций (как ISet)

. Они связаны с тем, что флаги представляют абстрактные группы отдельных членов коллекций.В этом конкретном случае коллекции представляют графства, города и очень широкие «регионы».Логические флаги предназначены для автора, чтобы указать, что сущность IsOutOfState, IsStatewide и / или IsEverywhere (например, Интернет).

Существуют дополнительные негеографические коллекции (например, Темы).Любое ограничение на это будет «и» с учетом географических ограничений.

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

Записывая это вручную в SQL, ясделать что-то вроде:

SELECT ... FROM foo LEFT JOIN FooCounties fc ON foo.ID = fc.ID 
LEFT JOIN FooCities fct ON foo.ID = fct.ID ...
INNER JOIN FooTopics ft ON foo.ID = ft.ID
WHERE (fc.CountyID IN (1, 2, ...) OR fct.CityID IN (1, 3, 5, ...) OR foo.IsStatewide = 1)
      AND ft.TopicID IN (1, 4, 7, ...)

Как я могу перевести это в QueryOver?До сих пор у меня были темы и другие критерии И, что-то вроде этого:

var query = Session.QueryOver<foo>();

if (SelectedTopicIDs.Count > 0) { 
  var TopicSubQ = QueryOver.Of<foo>().JoinQueryOver<Topic>(t => t.Topics)... etc.
  query = query.WithSubquery.WhereProperty(p => p.Id).In(TopicSubQ);
}

Но я не могу понять, как бы я использовал Disjunction, чтобы сравнить до 3 бул и до3 подзапроса, а затем объединить все как 'и' с существующими критериями.

1 Ответ

0 голосов
/ 20 сентября 2011
var query = session.QueryOver<foo>();
var or = new Disjunction().Add(Restrictions.Where<foo>(f => f.IsStatewide));

if (SelectedCountryIDs.Count > 0)
{
    Country countryAlias = null;
    var join = query.JoinAlias(f => f.Countries, () => countryAlias);
    or.Add(() => countryAlias.Id.IsIn(SelectedTopicIDs));
}

query.Where(or);

if (SelectedTopicIDs.Count > 0)
{
    Topic topicAlias = null;
    var join = query.JoinQueryOver<Topic>(f => f.Topics)
                    .WithSubquery.Where(() => topicAlias.Id).In(SelectedTopicIDs));
}
...