Как использовать PredicateBuilder с вложенными условиями OR в Linq - PullRequest
1 голос
/ 26 апреля 2010

Я очень рад, что использовал PredicateBuilder, но до сих пор использовал его только для запросов с только конкатенированными операторами AND или OR. Теперь в первый раз мне нужна пара операторов OR, вложенных вместе с некоторыми операторами AND вроде этого:

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

Используя документацию Албахари , я построил свое выражение так:

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 ИЛИ фразы.

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)

Если я попытаюсь использовать только такие фразы 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)

, что точно так же, как первый запрос. Кажется, я так близко, что должно быть что-то простое, что мне не хватает. Кто-нибудь может увидеть, что я здесь делаю не так?

Спасибо

Терри

1 Ответ

3 голосов
/ 26 апреля 2010

Разве это не должно быть:

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

вместо (предикат ИЛИ не устанавливается в переменную):

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