Nhibernate QueryOver Field1 = True OR(Collection contains ...)

时间:2011-09-19 15:18:41

标签: nhibernate queryover

我正在为搜索表单编写处理程序。被搜索的对象有3个布尔标志和几个集合(如ISet

这些是相关的,因为标志代表集合中各个成员的抽象分组。在这种特定情况下,馆藏代表县,城市和非常广泛的“区域”。布尔标志用于作者指定实体IsOutOfState,IsStatewide和/或IsEverywhere(例如Internet)。

还有其他非地理集合(例如主题)。对此的任何限制都将与地理限制“和”相符。

在搜索表单上,用户可以检查感兴趣的特定地理区域(特定县和/或城市和/或地区),以及扩大搜索范围,以包括设置了一个或多个额外布尔标志的项目(如果他们不选中该框,我们不会限制布尔字段。

在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?到目前为止,我已经通过以下方式获得了主题和其他AND标准:

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个bool和最多3个子查询,然后将它们全部合并为现有标准的“和”。

1 个答案:

答案 0 :(得分:0)

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