C# 在linq中应用多个表达式

C# 在linq中应用多个表达式,c#,linq,C#,Linq,在不同的场合使用不同类型的过滤器。如何在LinQ中应用多个过滤器 Expression<Func<data, bool>> filter = bt => bt.condition1 == condition1; Expression<Func<data, bool>> filter2 = bt => bt.condition2 == condition2;

在不同的场合使用不同类型的过滤器。如何在LinQ中应用多个过滤器

Expression<Func<data, bool>> filter =
                    bt => bt.condition1 == condition1;
Expression<Func<data, bool>> filter2 =
                    bt => bt.condition2 == condition2;
Expression<Func<data, bool>> filter3 =
                    bt => bt.condition3 == condition3;


var result = dataList.Where(filter1);
var result2 = dataList.Where(filter2, filter3); //Syntax error
var result3 = dataList.Where(filter2).Where(filter3); //Is this proper?
var result4 = dataList.Where(filter2 || filter3); //Syntax error
表达式过滤器=
bt=>bt.condition1==condition1;
表达式过滤器2=
bt=>bt.condition2==condition2;
表达式过滤器3=
bt=>bt.condition3==condition3;
var result=dataList.Where(filter1);
var result2=dataList.Where(filter2,filter3)//语法错误
var result3=dataList.Where(filter2).Where(filter3)//这样合适吗?
var result4=dataList.Where(filter2 | | filter3)//语法错误

对于要应用的每个筛选器,只需调用
。Where(filter)

您可以过滤
.Where()
再次返回的
IEnumerable
,过滤掉所有需要的元素

用法:

IEnumerable<someType> result = dataList.Where(filter1).Where(filter2).Where(filter3);
// equivalent to filter1|| filter2 || filter3
var result4 = dataList.Where(CombineWithOr(filter1, filter2, filter3)); 
IEnumerable result=dataList.Where(filter1)、Where(filter2)、Where(filter3);

您还可以将所有筛选条件放在一个表达式中,而不是放在多个表达式中。

您只需为要应用的每个筛选器调用
.Where(filter)

您可以过滤
.Where()
再次返回的
IEnumerable
,过滤掉所有需要的元素

用法:

IEnumerable<someType> result = dataList.Where(filter1).Where(filter2).Where(filter3);
// equivalent to filter1|| filter2 || filter3
var result4 = dataList.Where(CombineWithOr(filter1, filter2, filter3)); 
IEnumerable result=dataList.Where(filter1)、Where(filter2)、Where(filter3);
您还可以将所有过滤条件放在一个表达式中,而不是放在多个表达式中。

最佳实践

var query = fooContext.User.AsQueryable();

if (condition1!= null)
    query = query.Where(x => x.condition1==condition1);
if (condition2 != null)
    query = query.Where(x => x.condition2== condition2 );

return await query.ToList();
最佳实践

var query = fooContext.User.AsQueryable();

if (condition1!= null)
    query = query.Where(x => x.condition1==condition1);
if (condition2 != null)
    query = query.Where(x => x.condition2== condition2 );

return await query.ToList();

如果要使用和组合条件,可以只使用几个where运算符:

// equivalent to filter1 && filter2 && filter3
var result = dataList.Where(filter1).Where(filter2).Where(filter3); 

如果您想使用组合过滤器,或者它有点复杂,您需要手动操作表达式,我有一个小的util可以做到这一点:

public static Expression<Func<T, bool>> CombineWithOr<T>(params Expression<Func<T, bool>>[] filters)
{
    var first = filters.First();
    var param = first.Parameters.First();
    var body = first.Body;

    foreach(var other in filters.Skip(1))
    {
        var replacer = new ReplaceParameter
        {
            OriginalParameter = other.Parameters.First(),
            NewParameter = param
        };
        // We need to replace the original expression parameter with the result parameter
        body = Expression.Or(body, replacer.Visit(other.Body));
    }

    return Expression.Lambda<Func<T, bool>>(
        body,
        param
    );
}
class ReplaceParameter : ExpressionVisitor
{
    public Expression OriginalParameter { get; set; }
    public Expression NewParameter { get; set; }
    protected override Expression VisitParameter(ParameterExpression node)
    {
        return node == this.OriginalParameter ? this.NewParameter : base.VisitParameter(node);
    }
}

如果要使用和组合条件,可以只使用几个where运算符:

// equivalent to filter1 && filter2 && filter3
var result = dataList.Where(filter1).Where(filter2).Where(filter3); 

如果您想使用组合过滤器,或者它有点复杂,您需要手动操作表达式,我有一个小的util可以做到这一点:

public static Expression<Func<T, bool>> CombineWithOr<T>(params Expression<Func<T, bool>>[] filters)
{
    var first = filters.First();
    var param = first.Parameters.First();
    var body = first.Body;

    foreach(var other in filters.Skip(1))
    {
        var replacer = new ReplaceParameter
        {
            OriginalParameter = other.Parameters.First(),
            NewParameter = param
        };
        // We need to replace the original expression parameter with the result parameter
        body = Expression.Or(body, replacer.Visit(other.Body));
    }

    return Expression.Lambda<Func<T, bool>>(
        body,
        param
    );
}
class ReplaceParameter : ExpressionVisitor
{
    public Expression OriginalParameter { get; set; }
    public Expression NewParameter { get; set; }
    protected override Expression VisitParameter(ParameterExpression node)
    {
        return node == this.OriginalParameter ? this.NewParameter : base.VisitParameter(node);
    }
}

它取决于
数据列表的类型

如果它是
IEnumerable
,则可以使用函数而不是表达式,并为子句使用lambda函数:


它取决于
数据列表的类型

如果它是
IEnumerable
,则可以使用函数而不是表达式,并为子句使用lambda函数:


你不能简单地调用
dataList.Where(filter1).Where(filter2).Where(filter3)
?编辑:为什么这个解决方案应该是合适的?它基本上会过滤元素,并且匹配该过滤器的元素会再次过滤。条件不能聚合吗?那么它只是一个单一的数据列表,Where(filter1[&&/| |]filter2[&&/| |]filter3)
够了吗?要在筛选器之间进行组合,可以使用和/或布尔比较,或者使用连续的3个
Where
条件。您不能简单地调用
dataList.Where(filter1).Where(filter2).Where(filter3)
?编辑:此解决方案为什么合适?它基本上会过滤元素,并且匹配该过滤器的元素会再次过滤。条件不能聚合吗?那么它只是一个单一的数据列表,Where(filter1[&&/| |]filter2[&&/| |]filter3)
够了吗?要在筛选器之间进行组合,可以使用AND/OR布尔比较,或者使用连续的3
Where
条件。这是否与
dataList.Where相同(bt=>bt.condition1==condition1&&bt.condition2==condition2&&bt.condition3&&bt.condition3)当存在多个where@Z.V如果这些是你的过滤器,是的。仅当满足所有条件时,从比较中获得的布尔值才会计算为true。这与
dataList相同。其中(bt=>bt.condition1==condition1&&bt.condition2==condition2&&bt.condition3&&bt.condition3)当存在多个where@Z.V如果这些是你的过滤器,是的。从比较中得到的布尔值仅在满足所有条件时计算为true。不确定异步性的概念是否与此特定问题相关。我也不相信“最佳实践”对不起。我从我的项目中复制了代码。我忘记换衣服了。我已经更新了我的回答。不确定异步性的概念是否与这个特定的问题相关。我也不相信“最佳实践”对不起。我从我的项目中复制了代码。我忘记换衣服了。我已经更新了我的回复。