逐步构建OR查询表达式 [英] Build an OR query expression progressively

查看:69
本文介绍了逐步构建OR查询表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在LINQ中,可以逐步构建LINQ查询,如下所示:

In LINQ one can build a LINQ query progressively as follows:

var context = new AdventureWorksDataContext();
// Step 1
var query = context.Customers.Where(d => d.CustomerType == "Individual");
// Step 2
query = query.Where(d => d.TerritoryID == 3);

上面的查询将产生一个等效的SQL语句,该语句带有WHERE子句,该子句由两个谓词组成,这些谓词由 AND 逻辑运算符组合在一起,如下所示:

The above query would yield an equivalent SQL statement with a WHERE clause comprising of two predicates combined together by an AND logical operator like the following:

SELECT * FROM Customers WHERE CustomerType = 'Individual' AND TerritoryID = 3

是否可以构建LINQ查询以生成等效的SQL语句progressively,以使生成的查询具有WHERE子句,且其谓词由 OR 逻辑运算符组合在一起,如下所示? /p>

Can one build a LINQ query to yield an equivalent SQL statement, progressively, such that the resulting query has a WHERE clause with the predicates combined together by an OR logical operator as follows?

SELECT * FROM Customers WHERE CustomerType = 'Individual' OR TerritoryID = 3

推荐答案

您需要先构造过滤器,然后将过滤器组合为一个lambda,您可以将其用作组合查询:

You would need to construct the filters first, and then combine the filters into a single lambda that you can use as the composed query:

var filters = new List<Expression<Func<YourType, bool>>>();
filters.Add(d => d.TerritoryID == 3);
filters.Add(d => d.CustomerType == "Individual");
...

var lambda = AnyOf(filters.ToArray());
// this is: d => d.TerrotoryID == 3 || d.CustomerType == "Individual";

var data = src.Where(lambda);

使用:

static Expression<Func<T,bool>> AnyOf<T>(
          params Expression<Func<T,bool>>[] expressions)
{
    if (expressions == null || expressions.Length == 0) return x => false;
    if (expressions.Length == 1) return expressions[0];

    var body = expressions[0].Body;
    var param = expressions[0].Parameters.Single();
    for (int i = 1; i < expressions.Length; i++)
    {
        var expr = expressions[i];
        var swappedParam = new SwapVisitor(expr.Parameters.Single(), param)
                            .Visit(expr.Body);
        body = Expression.OrElse(body, swappedParam);
    }
    return Expression.Lambda<Func<T, bool>>(body, param);
}
class SwapVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public SwapVisitor(Expression from, Expression to){
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

这篇关于逐步构建OR查询表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆