我正在尝试在我的Web应用程序中创建一个过滤系统。问题是我不知道有多少过滤器将被请求从我的客户端到API。我已经构建了它,所以过滤器的数组来自一个像这样的字符串:第一个月
然后我使用string[] names = sizeFilters.Split(',');
来获得类似Where(x => x.listOfSizes.contains(names[index]));
的单个表达式
我还需要使用AND和OR来创建表达式的链,因为我将使用另一个过滤器,例如:'?typeFilters=normal,extra,spicy'
所以我需要使整个表达式看起来像这样,但它可能会长几倍,它需要使用不同大小的数组:
返回项目Where size is big OR small OR medium AND Where type is normal OR extra OR spicy
Where(x => x.Sizes == "Small" || x => x.Sizes == "Medium" || x => x.Sizes == "Big" &&
x => x.Types == "normal" || x => x.Types == "extra" || x => x.Types == "Spicy")
字符串
5条答案
按热度按时间2wnc66cl1#
您可以简单地多次调用
.Where
来一起执行AND表达式。对表达式进行动态OR运算要困难得多。您需要重新构建表达式图以包含OrElse
运算符,并确保所有表达式都基于相同的ParameterExpression
。字符串
编辑;由于这是写的,EF核心现在暴露了
ReplacingExpressionVisitor
,可以用来代替上面的Replacer
。mpbci0fu2#
正如其他人所指出的,最简单的选择是在表达式中使用
Enumerable.Contains
构建OR
;并通过多次调用Where
来构建AND
。字符串
如果需要,可以将此逻辑 Package 到一个扩展方法中,该方法接受一个要过滤的表达式,并接受一个
IEnumerable<string>
作为过滤器值;构造并应用Contains
方法:型
可以这样称呼:
型
一个警告:查询将基于传递到方法中的值来构建;如果它们后来被更改,查询将不会反映这些更改。如果这是一个问题:
Enumerable.Contains
的适当重载,而不是List.Contains
,以及Expression.Call
的重载,它产生一个静态方法调用,而不是示例方法调用。rdlzhqv93#
我想下面应该可以
字符串
ddrv8njm4#
你可以试试这个
字符串
ctehm74n5#
为了使它看起来整洁,我的建议是创建和扩展方法。这样,您就可以像使用任何其他LINQ方法一样使用它。参见extension methods demystified
假设您的源是
IQuertyable<TSource>
。字符串
用途:
型
注意:filterpredicates的空集合将不通过任何 predicate 进行过滤:你会得到原始数据:
型