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


所以 , 我们使用一个 CreateMinValueFilter 来创建这个表达式 。

[ Test] publicvoidExpression07( ) {varfilter = JoinSubFilters(Expression.AndAlso, CreateMinValueFilter( 1), x => x < 5); varre = Enumerable.Range( 0, 10).AsQueryable .Where(filter).ToList;varexpectation = Enumerable.Range( 1, 4); re.Should.BeEquivalentTo(expectation);Expression<Func< int, bool>> CreateMinValueFilter( intminValue) {returnx => x >= minValue; }
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; }}
工厂方法内部也可以使用Expression手动创建
当然 , 可以只使用 Expression 相关的方法来创建 x => x >= 1 。
[ Test] publicvoidExpression08( ) {varfilter = JoinSubFilters(Expression.AndAlso, CreateMinValueFilter( 1), x => x < 5); varre = Enumerable.Range( 0, 10).AsQueryable .Where(filter).ToList;varexpectation = Enumerable.Range( 1, 4); re.Should.BeEquivalentTo(expectation);Expression<Func< int, bool>> CreateMinValueFilter( intminValue) {// xvarpExp = Expression.Parameter( typeof( int), "x"); // minValuevarrightExp = Expression.Constant(minValue); // x >= minValuevarbodyExp = Expression.GreaterThanOrEqual(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; }}
同理 , 子表达式都可以如此创建
那既然都用了 Expression 来创建子表达式了 , 那就干脆再做一点点改进 , 把x => x < 5也做成从工厂方法获取 。

推荐阅读