Comment utiliser PredicateBuilder avec OR imbriqués dans LINQ conditionals
-
01-10-2019 - |
Question
J'ai été très heureux en utilisant PredicateBuilder mais jusqu'à présent seulement utilisé pour les requêtes avec seulement soit concaténé ET OU déclarations ou déclarations. Maintenant, pour la première fois que je besoin d'une paire de OU instructions imbriquées avec une certaine ET déclarations comme ceci:
select x from Table1 where a = 1 AND b = 2 AND (z = 1 OR y = 2)
Utilisation de la documentation de Albahari , j'ai construit mon expression comme ceci:
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);
Il en résulte SQL qui ignore complètement les 2 ou des phrases.
select x from TdIncSearchVw
where ((this_."TM_TEC" = :p0 and this_."TMS_TEC" = :p1)
and this_."HISTORY_IND" = :p2)
Si j'essayer d'utiliser seulement les OU phrases comme:
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);
Je SQL obtenir comme prévu comme:
select X from TdIncSearchVw
where (IncStatusInd = incStatus OR RqmtStatusInd = incStatus)
Si j'essayer d'utiliser seulement les ET phrases comme:
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);
Je reçois SQL comme:
select x from TdIncSearchVw
where ((this_."TM_TEC" = :p0 and this_."TMS_TEC" = :p1)
and this_."HISTORY_IND" = :p2)
ce qui est exactement la même que la première requête. Il semble que je suis si proche, il doit être simple quelque chose que je suis absent. Quelqu'un peut-il voir ce que je fais mal ici?
Merci,
Terry
La solution
ne doit pas être que:
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);
au lieu de (OU prédicat ne se réglé sur la variable):
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);