12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Text;
- namespace Ant.Service.Common
- {
- /// <summary>
- /// 谓词表达式构建器
- /// add 作者: 季健国 QQ:181589805 by 2016-09-08
- /// </summary>
- public static class PredicateBuilder
- {
- /// <summary>
- /// 机关函数应用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混应时写在AND后的OR有效
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public static Expression<Func<T, bool>> True<T>() { return f => true; }
- /// <summary>
- /// 机关函数应用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混应时写在OR后面的AND有效
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <returns></returns>
- public static Expression<Func<T, bool>> False<T>() { return f => false; }
- public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
- Expression<Func<T, bool>> expr2)
- {
- return expr1.Compose(expr2, Expression.Or);
- }
- public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
- Expression<Func<T, bool>> expr2)
- {
- return expr1.Compose(expr2, Expression.And);
- }
- public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
- {
- // build parameter map (from parameters of second to parameters of first)
- var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
- // replace parameters in the second lambda expression with parameters from the first
- var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
- // apply composition of lambda expression bodies to parameters from the first expression
- return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
- }
- }
- public class ParameterRebinder : ExpressionVisitor
- {
- private readonly Dictionary<ParameterExpression, ParameterExpression> map;
- public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
- {
- this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
- }
- public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
- {
- return new ParameterRebinder(map).Visit(exp);
- }
- protected override Expression VisitParameter(ParameterExpression p)
- {
- ParameterExpression replacement;
- if (map.TryGetValue(p, out replacement))
- {
- p = replacement;
- }
- return base.VisitParameter(p);
- }
- }
- }
|