using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace APT.Infrastructure.Core { /// /// Expression表达式扩展操作类 /// public static class ExpressionExtensions { /// /// 以特定的条件运行组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合条件运算方式 /// 组合后的表达式 public static Expression Compose(this Expression first, Expression second, Func merge) { Dictionary map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); Expression secondBody = ParameterRebinder.ReplaceParameters(map, second.Body); return Expression.Lambda(merge(first.Body, secondBody), first.Parameters); } /// /// 以 Expression.AndAlso 组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合后的表达式 public static Expression> And(this Expression> first, Expression> second) { return first.Compose(second, Expression.AndAlso); } /// /// 以 Expression.OrElse 组合两个Expression表达式 /// /// 表达式的主实体类型 /// 第一个Expression表达式 /// 要组合的Expression表达式 /// 组合后的表达式 public static Expression> Or(this Expression> first, Expression> second) { return first.Compose(second, Expression.OrElse); } private class ParameterRebinder : ExpressionVisitor { private readonly Dictionary _map; private ParameterRebinder(Dictionary map) { _map = map ?? new Dictionary(); } public static Expression ReplaceParameters(Dictionary map, Expression exp) { return new ParameterRebinder(map).Visit(exp); } protected override Expression VisitParameter(ParameterExpression node) { ParameterExpression replacement; if (_map.TryGetValue(node, out replacement)) { node = replacement; } return base.VisitParameter(node); } } } }