在不同的情况下使用不同类型的过滤器。如何在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
答案 0 :(得分:2)
您只需为要应用的每个过滤器调用.Where(filter)
即可。
您可以过滤IEnumerable<T>
再次返回的.Where()
,过滤掉您想要的所有元素。
用法:
IEnumerable<someType> result = dataList.Where(filter1).Where(filter2).Where(filter3);
你可以做的是在单个表达式中具有所有过滤条件,而不是多个过滤条件。
答案 1 :(得分:0)
最佳实践,
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();
答案 2 :(得分:0)
如果你想结合使用的条件,你可以使用几个运算符:
// equivalent to filter1 && filter2 && filter3
var result = dataList.Where(filter1).Where(filter2).Where(filter3);
如果你想要使用过滤器或者它有点复杂,你需要手动操作表达式,我有这个小的工具,可以做到这一点:
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);
}
}
用法:
// equivalent to filter1|| filter2 || filter3
var result4 = dataList.Where(CombineWithOr(filter1, filter2, filter3));
答案 3 :(得分:0)
这取决于dataList
的类型。
如果它是IEnumerable<data>
,那么你可以使用函数而不是表达式,以及Where子句的lambda函数:
Func<data, bool> filter = (bt => bt.condition1 == condition1);
Func<data, bool> filter2 = (bt => bt.condition2 == condition2);
Func<data, bool> filter3 = (bt => bt.condition3 == condition3);
var all = dataList.Where(d => filter1(d) && filter2(d) && filter3(d));
var any = dataList.Where(d => filter1(d) || filter2(d) || filter3(d));
但是,如果类型为IQueryable<data>
,则您需要对Where的可查询版本使用多次调用:
var all = dataList.Where(filter1).Where(filter2).Where(filter3);
var any = dataList.Where(filter1)
.Union(dataList.Where(filter2))
.Union(dataList.Where(filter3))
.Distinct();