Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 逐步构建OR查询表达式_C#_.net_Sql_Linq - Fatal编程技术网

C# 逐步构建OR查询表达式

C# 逐步构建OR查询表达式,c#,.net,sql,linq,C#,.net,Sql,Linq,在LINQ中,可以按如下方式逐步构建LINQ查询: 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子

在LINQ中,可以按如下方式逐步构建LINQ查询:

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子句,该子句由一个逻辑运算符组合在一起的两个谓词组成,如下所示:

SELECT * FROM Customers WHERE CustomerType = 'Individual' AND TerritoryID = 3
可以构建一个LINQ查询来生成一个等价的SQL语句,
逐步地
,这样生成的查询就有一个WHERE子句,其中谓词由逻辑运算符组合在一起,如下所示

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

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

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);
var过滤器=新列表();
filters.Add(d=>d.TerritoryID==3);
filters.Add(d=>d.CustomerType==“个人”);
...
var lambda=AnyOf(filters.ToArray());
//这是:d=>d.TerrotoryID==3 | | d.CustomerType==“个人”;
var数据=src.Where(λ);
使用:

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);
    }
}
AnyOf的静态表达式(
参数表达式[]表达式)
{
if(expressions==null | | expressions.Length==0)返回x=>false;
if(expressions.Length==1)返回表达式[0];
var body=表达式[0]。body;
var param=表达式[0]。参数。Single();
for(int i=1;i
您需要首先构造过滤器,然后将过滤器组合成一个lambda,您可以将其用作组合查询:

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);
var过滤器=新列表();
filters.Add(d=>d.TerritoryID==3);
filters.Add(d=>d.CustomerType==“个人”);
...
var lambda=AnyOf(filters.ToArray());
//这是:d=>d.TerrotoryID==3 | | d.CustomerType==“个人”;
var数据=src.Where(λ);
使用:

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);
    }
}
AnyOf的静态表达式(
参数表达式[]表达式)
{
if(expressions==null | | expressions.Length==0)返回x=>false;
if(expressions.Length==1)返回表达式[0];
var body=表达式[0]。body;
var param=表达式[0]。参数。Single();
for(int i=1;i
如果需要分两步进行,可以使用union:

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

var context=new AdventureWorksDataContext();
//第一步
var query=context.Customers.Where(d=>d.CustomerType==“个人”);
//步骤2
query=query.Union(context.Customers.Where(d=>d.TerritoryID==3));

如果需要分两步进行,可以使用union:

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

var context=new AdventureWorksDataContext();
//第一步
var query=context.Customers.Where(d=>d.CustomerType==“个人”);
//步骤2
query=query.Union(context.Customers.Where(d=>d.TerritoryID==3));

要在不使用动态linq库的情况下完成您的要求,您可以在where子句中为每个测试定义表达式,然后使用它们构建lambda表达式:

Expression<Func<Customer, bool>> isIndividualCustomer = c => c.CustomerType == "Individual";

Expression<Func<Customer, bool>> territoryIdIs3 = c => c.TerritoryID == 3;

Expression<Func<Car, bool>> customerIsIndividualOrOfTerritoryId3 = Expression.Lambda<Func<Customer, bool>>(
    Expression.Or(isIndividualCustomer.Body, territoryIdIs3.Body), isIndividualCustomer.Parameters.Single());

要在不使用动态linq库的情况下完成您的要求,可以在where子句中为每个测试定义表达式,然后使用它们构建lambda表达式:

Expression<Func<Customer, bool>> isIndividualCustomer = c => c.CustomerType == "Individual";

Expression<Func<Customer, bool>> territoryIdIs3 = c => c.TerritoryID == 3;

Expression<Func<Car, bool>> customerIsIndividualOrOfTerritoryId3 = Expression.Lambda<Func<Customer, bool>>(
    Expression.Or(isIndividualCustomer.Body, territoryIdIs3.Body), isIndividualCustomer.Parameters.Single());

虽然您可以直接执行这类操作,但我使用LinqKit库,这使得这种渐进式查询构建非常简单:

你最终会得到:

var context = new AdventureWorksDataContext();
// Step 1
var query = context.Customers.Where(d => d.CustomerType == "Individual");
// Step 2
query = query.Or(d => d.TerritoryID == 3);
我正在开发的系统需要很多这样的功能,而LinqKit是一个主要的救生工具。你可以找到它


(注意:无论如何,我不是LinqKit的开发者——我只是一个粉丝。)

虽然你可以直接做这类事情,但我使用LinqKit库,这使得这种渐进式查询构建非常简单:

你最终会得到:

var context = new AdventureWorksDataContext();
// Step 1
var query = context.Customers.Where(d => d.CustomerType == "Individual");
// Step 2
query = query.Or(d => d.TerritoryID == 3);
我正在开发的系统需要很多这样的功能,而LinqKit是一个主要的救生工具。你可以找到它


(注意:无论如何,我不是LinqKit的开发者——只是一个粉丝。)

为什么不
Where(d=>d.TerritoryID==3 | | CustomerType='Individual')?请参见以下答案:@CuongLe:在某些情况下,您需要逐步构建查询。正如我在上面演示的那样,LINQ为您提供了这种能力,结果谓词使用and逻辑运算符进行组合。我寻求的是一种同样的方法,但是使用OR逻辑运算符组合谓词为什么不
Where(d=>d.TerritoryID==3 | | CustomerType='single')?请参见以下答案:@CuongLe:在某些情况下,您需要逐步构建查询。正如我在上面演示的那样,LINQ为您提供了这种能力,结果谓词使用and逻辑运算符进行组合。我所寻求的是一种同样的方法,但是使用OR逻辑运算符important组合谓词:“从作用域“”引用类型为'Customer'的变量'c',但它未定义”(这是从运行时开始的;如果不重新映射参数,您就不能这样做,例如通过访问者);此外,应为
OrElse
,而不是
。非常轻微,bu