将LINQ中的多个where子句连接为OR而不是AND

无论如何加入LINQ的条款是OR吗?

var ints = new [] { 1, 3, 5, 7 }; var query = from i in ints select i; query = query.Where (q => q == 3); query = query..Where (q => q == 7); 

我想要的是能够动态添加where子句但是使用OR而不是AND

如果你想继续使用强类型的Linq查询,你应该查看LinqKit和谓词构建。 我已经将它用于类似的东西,并发现它与And / Or堆叠filter配合得很好。

在Nutshell摘录中查看C#4.0 / 3.0以获取更多深入信息。 这是我的代码中的一个片段:

  //Setup the initial predicate obj then stack on others: basePredicate = basePredicate.And(p => false); var predicate1 = PredicateBuilder.True(); foreach (SearchParms parm in parms) { switch (parm.field) { case "firstname": predicate1 = predicate1.And(p => p.FirstName.Trim().ToLower().Contains(sValue)); break; //etc... } } //Run a switch based on your and/or parm value to determine stacking: if (Parm.isAnd) { basePredicate = basePredicate.And(predicate1); } else { basePredicate = basePredicate.Or(predicate1); } 

这样的事怎么样?

 var query = from i in ints where CheckConditions(i) select i; public bool CheckConditions(int i) { var conditions = WhereConditions; //an IEnumerable> of dynamically added conditions foreach (var condition in conditions) { if (condition(i)) return true; } return false; } 

你可以扩展这个有点聪明,但这就是我的方式。

编辑:对不起,第一个例子是AND,现在已将其更改为OR。 所以第一次遇到传递条件时它返回true。

使用ExpressionVisitor帮助构建基于具有OR / AND关系的两个表达式的表达式。 这个答案来自Jeffery Zhao的博客 。

 internal class ParameterReplacer : ExpressionVisitor { public ParameterReplacer(ParameterExpression paramExpr) { this.ParameterExpression = paramExpr; } public ParameterExpression ParameterExpression { get; private set; } public Expression Replace(Expression expr) { return this.Visit(expr); } protected override Expression VisitParameter(ParameterExpression p) { return this.ParameterExpression; } } public static Expression> And(this Expression> one, Expression> another) { var candidateExpr = Expression.Parameter(typeof(T), "candidate"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(one.Body); var right = parameterReplacer.Replace(another.Body); var body = Expression.And(left, right); return Expression.Lambda>(body, candidateExpr); } public static Expression> Or(this Expression> one, Expression> another) { var candidateExpr = Expression.Parameter(typeof(T), "candidate"); var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(one.Body); var right = parameterReplacer.Replace(another.Body); var body = Expression.Or(left, right); return Expression.Lambda>(body, candidateExpr); } 

您可以使用Union方法:

 var ints = new [] { 1, 3, 5, 7 }; var query = ints.Where(q => q == 3); query = query.Union(ints.Where(q => q == 7)); 

你在谈论在lambda中指定多个条件吗?

 query = query.Where(q => q == 3 || q == 7); 

试试这个

var ints = new [] { 1, 3, 5, 7 };

var query = ints.select(X=>X).where(X=>X==3||X==7);

我正在尝试做类似的事情。 这就是我想出的:

 //various test cases bool useTestCase1 = true; bool useTestCase2 = true; bool useTestCase3 = false; query = query.Where(q => (q == 3 && useTestCase1 ) || (q == 7 && useTestCase2 ) || (q == 10 && useTestCase3 ) );