我正在为搜索表单编写处理程序。被搜索的对象有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个子查询,然后将它们全部合并为现有标准的“和”。
答案 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));
}