2

我一直非常高兴地使用 PredicateBuilder,但直到现在只将它用于只有连接 AND 语句或 OR 语句的查询。现在我第一次需要一对嵌套的 OR 语句和一些 AND 语句,如下所示:

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)

如果我尝试仅使用 OR 短语,例如:

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)

如果我尝试仅使用 AND 短语,例如:

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)

这与第一个查询完全相同。看起来我很接近它一定是我错过的一些简单的东西。谁能看到我在这里做错了什么?

谢谢,

特里

4

1 回答 1

4

那不应该是:

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);
于 2010-04-26T17:41:44.677 回答