C# 将LINQ中的多个where子句连接为或代替AND

C# 将LINQ中的多个where子句连接为或代替AND,c#,linq,C#,Linq,是否仍有将LINQ where子句作为或加入 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您是说在lambda中指定多个条件吗 query = query.Where(q

是否仍有将LINQ where子句作为或加入

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

您是说在lambda中指定多个条件吗

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

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


var query=ints.select(X=>X).其中(X=>X==3 | | X==7)

如果您想继续使用强类型Linq查询,您应该查看LinqKit和谓词构建。我用它做了一些类似的事情,发现它可以很好地处理和/或堆叠过滤器

有关更深入的信息,请查看。下面是我代码中的一个片段:

        //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);
        }
//设置初始谓词obj,然后在其他对象上堆叠:
basePredicate=basePredicate.And(p=>false);
var predicate1=PredicateBuilder.True();
foreach(SearchParms parm in parms)
{
开关(参数字段)
{
案例“名字”:
predicate1=predicate1.And(p=>p.FirstName.Trim().ToLower().Contains(sValue));
打破
//等等。。。
}
}
//根据您的和/或parm值运行开关以确定堆叠:
如果(按isAnd参数){
basePredicate=basePredicate.And(谓词1);
}否则{
basePredicate=basePredicate.Or(谓词1);
}

像这样的东西怎么样

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;
}
var query=ints中的from i,其中CheckConditions(i)选择i;
公共布尔检查条件(int i)
{
var conditions=WhereConditions;//动态添加的条件的IEnumerable
foreach(条件中的var条件)
{
如果(条件(i))返回true;
}
返回false;
}
你可以把它扩展到更聪明一点,但我就是这么做的


编辑:很抱歉,第一个示例是和,现在已将其更改为或。因此,当它第一次遇到传递条件时,它将返回true。

使用
ExpressionVisitor
帮助在具有或/和关系的两个表达式的基础上构建表达式。这个答案来自于

内部类参数replacer:ExpressionVisitor
{
公共参数置换器(参数表达式参数置换器)
{
this.ParameterExpression=parameterxpr;
}
公共参数表达式参数表达式{get;private set;}
公共表达式替换(表达式表达式表达式)
{
回访(expr);
}
受保护的重写表达式VisitParameter(ParameterExpression p)
{
返回this.ParameterExpression;
}
}
公共静态表达式和(此表达式一个,表达式另一个)
{
var candidateExpr=Expression.Parameter(typeof(T),“candidate”);
var parameterReplacer=新的parameterReplacer(candidateExpr);
var left=参数更换器更换(一个主体);
var right=参数replacer.Replace(另一个主体);
var body=表达式和(左、右);
返回表达式.Lambda(body,candidatexpr);
}
公共静态表达式或(此表达式,一个表达式,另一个表达式)
{
var candidateExpr=Expression.Parameter(typeof(T),“candidate”);
var parameterReplacer=新的parameterReplacer(candidateExpr);
var left=参数更换器更换(一个主体);
var right=参数replacer.Replace(另一个主体);
变量体=表达式。或(左、右);
返回表达式.Lambda(body,candidatexpr);
}

我正在尝试做类似的事情。以下是我的想法:

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

您可以使用Union方法:

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

这仍然不是动态的解决方案。是的,听起来像是一条路要走——或者他可以使用DLINQ?有趣的解决方案。我们正在寻找一种没有单独lib的方法,但为什么要重新发明轮子:)即使从linqKit开始,也不要担心,对于使用此方法的特定解决方案,仍有许多代码需要“发明”。
var ints = new [] { 1, 3, 5, 7 };
var query = ints.Where(q => q == 3);
query = query.Union(ints.Where(q => q == 7));