无论如何加入LINQ where子句为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
答案 0 :(得分:14)
如果您想继续使用强类型Linq查询,您应该查看LinqKit和谓词构建。我已经将它用于类似的东西,并发现它与And / Or堆叠过滤器一起使用。
查看C#4.0/3.0 in a Nutshell excerpt以获取更多深度信息。以下是我的代码片段:
//Setup the initial predicate obj then stack on others:
basePredicate = basePredicate.And(p => false);
var predicate1 = PredicateBuilder.True<Person>();
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);
}
答案 1 :(得分:2)
这样的事情怎么样?
var query = from i in ints where CheckConditions(i) select i;
public bool CheckConditions(int i)
{
var conditions = WhereConditions; //an IEnumerable<Func<int, bool>> of dynamically added conditions
foreach (var condition in conditions)
{
if (condition(i)) return true;
}
return false;
}
你可以扩展这个有点聪明,但这就是我的方式。
编辑:抱歉,第一个例子是AND,现在已将其更改为OR。所以第一次遇到传递条件时它返回true。答案 2 :(得分:2)
使用ExpressionVisitor
帮助构建基于具有OR / AND关系的两个表达式的表达式。这个答案来自Jeffery Zhao's blog。
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<Func<T, bool>> And<T>(this Expression<Func<T, bool>> one, Expression<Func<T, bool>> 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<Func<T, bool>>(body, candidateExpr);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> one, Expression<Func<T, bool>> 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<Func<T, bool>>(body, candidateExpr);
}
答案 3 :(得分:0)
您可以使用Union方法:
import acm.program.*;
public class Morse extends Program{
public void run(){
println("Hello, please enter the text that you want to convert to Morse.");
String txt = readLine();
txt = txt.toUpperCase();
for(int j = 0;j <= txt.length()-1;j++){
int i;
for (i=0;i<=26;i++){ //alphabet[26] is a white space
if (alphabet[i]==txt.charAt(j)){
if (txt.charAt(j)==' '){
System.out.print(System.lineSeparator());
}else{
System.out.print(" " + code[i] + " ");
}
}
}
}
}
private final String[] code = { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.","--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-","-.--", "--..","\n"};
private final char[] alphabet = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' '};
}
答案 4 :(得分:-2)
你是在谈论在lambda中指定多个条件吗?
query = query.Where(q => q == 3 ||
q == 7);
答案 5 :(得分:-3)
试试这个
var ints = new [] { 1, 3, 5, 7 };
var query = ints.select(X=>X).where(X=>X==3||X==7);
答案 6 :(得分:-3)
我正在尝试做类似的事情。这就是我想出的:
//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 )
);