动态|如何完成复杂查询的动态构建?( 五 )


[ Test] publicvoidExpression09( ) {varfilter = JoinSubFilters(Expression.AndAlso, CreateValueCompareFilter(Expression.GreaterThanOrEqual, 1), CreateValueCompareFilter(Expression.LessThan, 5)); varre = Enumerable.Range( 0, 10).AsQueryable .Where(filter).ToList;varexpectation = Enumerable.Range( 1, 4); re.Should.BeEquivalentTo(expectation);Expression<Func< int, bool>> CreateValueCompareFilter(Func<Expression, Expression, Expression> comparerFunc, intrightValue) {varpExp = Expression.Parameter( typeof( int), "x"); varrightExp = Expression.Constant(rightValue); varbodyExp = comparerFunc(pExp, rightExp); varresult = Expression.Lambda<Func< int, bool>>(bodyExp, pExp); returnresult; }
Expression<Func< int, bool>> JoinSubFilters(Func<Expression, Expression, Expression> expJoiner, paramsExpression<Func< int, bool>>[] subFilters) {// xvarpExp = Expression.Parameter( typeof( int), "x"); varresult = subFilters[ 0]; foreach( varsub insubFilters[ 1..]) {varleftExp = result.Unwrap(pExp); varrightExp = sub.Unwrap(pExp); varbodyExp = expJoiner(leftExp, rightExp);
result = Expression.Lambda<Func< int, bool>>(bodyExp, pExp); }
returnresult; }}
加入一点点配置 , 就完成了
最后 , 我们在把子表达式的创建通过一点点小技巧 。 通过外部参数来决定 。 就基本完成了一个多 And 的值比较查询条件的动态构建 。
[ Test] publicvoidExpression10( ) {varconfig = newDictionary< string, int> {{ ">=", 1}, { "<", 5} };varsubFilters = config.Select(x => CreateValueCompareFilter(MapConfig(x.Key), x.Value)).ToArray; varfilter = JoinSubFilters(Expression.AndAlso, subFilters); varre = Enumerable.Range( 0, 10).AsQueryable .Where(filter).ToList;varexpectation = Enumerable.Range( 1, 4); re.Should.BeEquivalentTo(expectation);Func<Expression, Expression, Expression> MapConfig( stringop ) {returnop switch{">="=> Expression.GreaterThanOrEqual, "<"=> Expression.LessThan, _ => thrownewArgumentOutOfRangeException( nameof(op)) };}
Expression<Func< int, bool>> CreateValueCompareFilter(Func<Expression, Expression, Expression> comparerFunc, intrightValue) {varpExp = Expression.Parameter( typeof( int), "x"); varrightExp = Expression.Constant(rightValue); varbodyExp = comparerFunc(pExp, rightExp); varresult = Expression.Lambda<Func< int, bool>>(bodyExp, pExp); returnresult; }

推荐阅读