Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# Linq:嵌套子查询中的动态Where子句_C#_Linq_Predicatebuilder - Fatal编程技术网

C# Linq:嵌套子查询中的动态Where子句

C# Linq:嵌套子查询中的动态Where子句,c#,linq,predicatebuilder,C#,Linq,Predicatebuilder,在过去,我通过向Linq查询动态添加过滤器来处理可选搜索条件,如下所示: public IEnumerable FindCustomers(字符串名称) { IEnumerable customers=GetCustomers(); var results=customers.AsQueryable(); if(name!=null) { 结果=结果。其中(customer=>customer.Name==Name); } results=results.OrderBy(customer=>cu

在过去,我通过向Linq查询动态添加过滤器来处理可选搜索条件,如下所示:

public IEnumerable FindCustomers(字符串名称)
{
IEnumerable customers=GetCustomers();
var results=customers.AsQueryable();
if(name!=null)
{
结果=结果。其中(customer=>customer.Name==Name);
}
results=results.OrderBy(customer=>customer.Name);
返回结果;
}
或者类似地使用谓词,基本上只需将lambda从where移动到
Func
或表达式,如果使用linqtoenties),如下所示:

public IEnumerable FindCustomers(字符串名称)
{
Func searchPredicate=customer=>true;
if(name!=null)
{
searchPredicate=customer=>customer.Name==Name;
}
IEnumerable customers=GetCustomers();
var结果=客户
.Where(搜索谓词)
.OrderBy(customer=>customer.Name);
返回结果;
}
但是,当Where子句埋在嵌套子查询中的某个地方时,我不知道如何执行类似的操作。考虑下面的(虚构的)场景:

公共类客户
{
公共字符串名称;
公共整数MaxOrderItemAmount;
公共信息收集未决订单;
公共i收集失败的命令;
公共i收集完成订单;
}
公共阶级秩序
{
公共int Id;
公共信息收集项目;
}
公共类OrderItem
{
公共整数金额;
}
公共IEnumerable FindInterestingOrderItems(
bool仅包括依赖项SOVERLIMIT)
{
var customers=GetCustomersWithOrders();
//这种方法可行,但会产生不必要的复杂SQL
//onlyIncludePendingItemsOverLimit为false时的查询
var interestingOrderItems=客户
.SelectMany(customer=>customer.PendingOrders
.SelectMany(订单=>order.Items
.Where(orderItem=>onlyIncludePendingItemsOverLimit==false
||orderItem.Amount>customer.MaxOrderItemAmount)
.Union(客户失败订单)
);
//相反,我希望仅在需要时动态添加Where子句:
Func pendingOrderItemPredicate=orderItem=>true;
如果(仅包括dependingingitemsoverlimit)
{
pendingOrderItemPredicate=
orderItem=>orderItem.Amount>customer.MaxOrderItemAmount;
//问题:此处未定义客户^^^
}
interestingOrderItems=客户
.SelectMany(customer=>customer.PendingOrders
.SelectMany(订单=>order.Items
.其中(待决或待决预测)
.Union(customer.FailedOrderItems)))
.OrderByDescending(orderItem=>orderItem.Amount);
返回利息订单项目;
}

显然,这次我不能将lambda移动到
Func
,因为它包含对由查询的更高级部分定义的变量(
customer
)的引用。我在这里遗漏了什么?

这是可行的:在一个单独的函数中构建谓词,将来自更高级别lambda的“customer”值作为参数传递

publicvoid FindInterestingOrderItems(bool onlyIncludePendingItemsOverLimit)
{
    var customers = GetCustomersWithOrders();
    var interestingOrderItems = customers
        .SelectMany(customer => customer.PendingOrders
            .SelectMany(order => order.Items
                .Where(GetFilter(customer, onlyIncludePendingItemsOverLimit))
            .Union(customer.FailedOrderItems)))
        .OrderByDescending(orderItem => orderItem.Amount);
}

private Func<OrderItem, bool> GetFilter(Customer customer, bool onlyIncludePendingItemsOverLimit)
{
    if (onlyIncludePendingItemsOverLimit)
    {
        return orderItem => orderItem.Amount > customer.MaxOrderItemAmount;
    }
    else
    {
        return orderItem => true;
    }
}
publicvoid FindInterestingOrderItems(仅限bool,包括依赖项SoverLimit)
{
var customers=GetCustomersWithOrders();
var interestingOrderItems=客户
.SelectMany(customer=>customer.PendingOrders
.SelectMany(订单=>order.Items
.Where(GetFilter(客户,仅包括DependingItemsOverLimit))
.Union(customer.FailedOrderItems)))
.OrderByDescending(orderItem=>orderItem.Amount);
}
private Func GetFilter(客户,仅限bool,包括DependingItemsOverLimit)
{
如果(仅包括dependingingitemsoverlimit)
{
return orderItem=>orderItem.Amount>customer.MaxOrderItemAmount;
}
其他的
{
returnorderItem=>true;
}
}

这是可行的:在一个单独的函数中构建谓词,将来自更高级别lambda的“customer”值作为参数传递

publicvoid FindInterestingOrderItems(bool onlyIncludePendingItemsOverLimit)
{
    var customers = GetCustomersWithOrders();
    var interestingOrderItems = customers
        .SelectMany(customer => customer.PendingOrders
            .SelectMany(order => order.Items
                .Where(GetFilter(customer, onlyIncludePendingItemsOverLimit))
            .Union(customer.FailedOrderItems)))
        .OrderByDescending(orderItem => orderItem.Amount);
}

private Func<OrderItem, bool> GetFilter(Customer customer, bool onlyIncludePendingItemsOverLimit)
{
    if (onlyIncludePendingItemsOverLimit)
    {
        return orderItem => orderItem.Amount > customer.MaxOrderItemAmount;
    }
    else
    {
        return orderItem => true;
    }
}
publicvoid FindInterestingOrderItems(仅限bool,包括依赖项SoverLimit)
{
var customers=GetCustomersWithOrders();
var interestingOrderItems=客户
.SelectMany(customer=>customer.PendingOrders
.SelectMany(订单=>order.Items
.Where(GetFilter(客户,仅包括DependingItemsOverLimit))
.Union(customer.FailedOrderItems)))
.OrderByDescending(orderItem=>orderItem.Amount);
}
private Func GetFilter(客户,仅限bool,包括DependingItemsOverLimit)
{
如果(仅包括dependingingitemsoverlimit)
{
return orderItem=>orderItem.Amount>customer.MaxOrderItemAmount;
}
其他的
{
returnorderItem=>true;
}
}