2011-09-19 71 views
1

我正在为搜索表单编写处理程序。正在搜索的对象有3个布尔标志和若干个集合(如ISetNhibernate QueryOver Field1 = True OR(Collection contains ...)

这些相关之处在于标志表示集合中各个成员的抽象分组。在这个具体情况下,收集代表县,城市和非常广泛的“地区”。布尔标志用于作者指定实体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?到目前为止,我的东西得到了主题和其他和标准确定这样的:

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子查询和然后将这些全部合并为现有标准的'和'。

回答

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

我认为这是正确的轨道上,但它不喜欢的query.JoinQueryOver: 无法转换类型'System.Linq.Expressions.MethodCallExpressionN为键入“System.Linq.Expressions的对象.BinaryExpression”。 第110行:主题topicAlias = null; Line 111:var join = query.JoinQueryOver (f => f.Topics) Line 112:.WithSubquery.Where(()=> topicAlias.Id.IsIn(TopicIDs));我想尝试重写子查询如何让他们... –

+0

'var TopicSubQuery = QueryOver.Of ().JoinQueryOver (p => p.Topics).WhereRestrictionOn(t => t.Id).InInG (TopicIDs)\t \t \t \t .Select(Projections.Property (p => p.Id)); \t \t \t \t query = query.WithSubquery.WhereProperty(p => p.Id).In(TopicSubQuery);'似乎适用于子查询。仍然编写更多的测试来证明它完全按预期工作。 –