2010-04-26 30 views
1

我一直非常高兴地使用PredicateBuilder,但到现在为止只用于只有连接的AND语句或OR语句的查询。现在,第一次,我需要一双或报表连同一些和语句这样嵌套:如何在Linq中使用嵌套或条件式的PredicateBuilder

select x from Table1 where a = 1 AND b = 2 AND (z = 1 OR y = 2) 

使用从Albahari的文件,我已经构建我的表情是这样的:

Expression<Func<TdIncSearchVw, bool>> predicate = 
    PredicateBuilder.True<TdIncSearchVw>(); // for AND 
Expression<Func<TdIncSearchVw, bool>> innerOrPredicate = 
    PredicateBuilder.False<TdIncSearchVw>(); // for OR 

innerOrPredicate = innerOrPredicate.Or(i=> i.IncStatusInd.Equals(incStatus)); 
innerOrPredicate = innerOrPredicate.Or(i=> i.RqmtStatusInd.Equals(incStatus)); 

predicate = predicate.And(i => i.TmTec.Equals(tecTm)); 
predicate = predicate.And(i => i.TmsTec.Equals(series)); 
predicate = predicate.And(i => i.HistoryInd.Equals(historyInd)); 

predicate.And(innerOrPredicate); 
var query = repo.GetEnumerable(predicate); 

这会导致SQL完全忽略2个OR短语。

select x from TdIncSearchVw 
    where ((this_."TM_TEC" = :p0 and this_."TMS_TEC" = :p1) 
    and this_."HISTORY_IND" = :p2) 

如果我尝试使用刚刚或短语,如:

Expression<Func<TdIncSearchVw, bool>> innerOrPredicate = 
    PredicateBuilder.False<TdIncSearchVw>(); // for OR 
innerOrPredicate = innerOrPredicate.Or(i=> i.IncStatusInd.Equals(incStatus)); 
innerOrPredicate = innerOrPredicate.Or(i=> i.RqmtStatusInd.Equals(incStatus)); 
var query = repo.GetEnumerable(innerOrPredicate); 

我得到SQL如预期一样:

select X from TdIncSearchVw 
    where (IncStatusInd = incStatus OR RqmtStatusInd = incStatus) 

如果我尝试使用刚刚和词组,例如:

predicate = predicate.And(i => i.TmTec.Equals(tecTm)); 
predicate = predicate.And(i => i.TmsTec.Equals(series)); 
predicate = predicate.And(i => i.HistoryInd.Equals(historyInd)); 
var query = repo.GetEnumerable(predicate); 

我得到SQL如:

select x from TdIncSearchVw 
    where ((this_."TM_TEC" = :p0 and this_."TMS_TEC" = :p1) 
    and this_."HISTORY_IND" = :p2) 

这与第一个查询完全相同。看起来我太亲密了,一定很简单,我错过了。任何人都可以看到我在这里做错了吗?

感谢,

特里

回答

3

难道不应该是:

predicate = predicate.And(i => i.TmTec.Equals(tecTm)); 
predicate = predicate.And(i => i.TmsTec.Equals(series)); 
predicate = predicate.And(i => i.HistoryInd.Equals(historyInd)); 

predicate = predicate.And(innerOrPredicate); 
var query = repo.GetEnumerable(predicate); 

,而不是(OR谓词不获取设置为可变):

predicate = predicate.And(i => i.TmTec.Equals(tecTm)); 
predicate = predicate.And(i => i.TmsTec.Equals(series)); 
predicate = predicate.And(i => i.HistoryInd.Equals(historyInd)); 

predicate.And(innerOrPredicate); 
var query = repo.GetEnumerable(predicate); 
+0

卫生署!我一定要双目失明,谢谢你指出我明显的错误。 – tblank 2010-04-26 19:10:01