動態拼接Lambda表示式2
阿新 • • 發佈:2020-12-02
動態拼接Lambda表示式
新增類
#region lambda expression 拼接方式1 /// <summary> /// Expression表示式樹 /// </summary> public class LambdaParameteRebinder : ExpressionVisitor { /// <summary> /// 存放表示式樹的引數的字典 /// </summary> private readonly Dictionary<ParameterExpression, ParameterExpression> map;/// <summary> /// 建構函式 /// </summary> /// <param name="map"></param> public LambdaParameteRebinder(Dictionary<ParameterExpression, ParameterExpression> map) { this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>(); }/// <summary> /// 過載引數訪問的方法,訪問表示式樹引數,如果字典中包含,則取出 /// </summary> /// <param name="node">表示式樹引數</param> /// <returns></returns> protected override Expression VisitParameter(ParameterExpression node) { if (map.TryGetValue(node, outParameterExpression expression)) { node = expression; } return base.VisitParameter(node); } public static Expression ReplaceParameter(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp) { return new LambdaParameteRebinder(map).Visit(exp); } } /// <summary> /// 表示式數的lambda引數的拼接擴充套件方法 /// </summary> public static class LambdaExtension { /// <summary> /// Expression表示式樹lambda引數拼接組合 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <param name="merge"></param> /// <returns></returns> public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge) { var parameterMap = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f); var secondBody = LambdaParameteRebinder.ReplaceParameter(parameterMap, second.Body); return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters); } /// <summary> /// Expression表示式樹lambda引數拼接--false /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool>> False<T>() => f => false; /// <summary> /// Expression表示式樹lambda引數拼接-true /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static Expression<Func<T, bool>> True<T>() => f => true; /// <summary> /// Expression表示式樹lambda引數拼接--and /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) => first.Compose(second, Expression.And); /// <summary> /// Expression表示式樹lambda引數拼接--or /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) => first.Compose(second, Expression.Or); } #endregion #region lambda expression 拼接方式2 /// <summary> /// 表示式數的lambda引數的拼接擴充套件方法擴充套件類 /// </summary> public class LambdaExpressionParameter : ExpressionVisitor { /// <summary> /// 表示式數的lambda引數 /// </summary> public ParameterExpression parameterExpression { get; private set; } /// <summary> /// 建構函式 /// </summary> /// <param name="parameterExpression"></param> public LambdaExpressionParameter(ParameterExpression parameterExpression) { this.parameterExpression = parameterExpression; } /// <summary> /// 替代方法 /// </summary> /// <param name="expression"></param> /// <returns></returns> public Expression Replace(Expression expression) { return base.Visit(expression); } /// <summary> /// 過載引數訪問的方法,處理引數表示式 /// </summary> /// <param name="node"></param> /// <returns></returns> protected override Expression VisitParameter(ParameterExpression node) { return this.parameterExpression; } } /// <summary> /// 表示式數的lambda引數的拼接擴充套件方法 /// </summary> public static class LambdaExpressionExtend { /// <summary> /// Expression表示式樹lambda引數拼接--and /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> And1<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { //var param = first.Parameters[0]; var param = Expression.Parameter(typeof(T), "w");//指定引數和引數名稱 LambdaExpressionParameter lambdaExpression = new LambdaExpressionParameter(param); var left = lambdaExpression.Replace(first.Body); var right = lambdaExpression.Replace(second.Body); var body = Expression.And(left, right); return Expression.Lambda<Func<T, bool>>(body, param); } /// <summary> /// Expression表示式樹lambda引數拼接--or /// </summary> /// <typeparam name="T"></typeparam> /// <param name="first"></param> /// <param name="second"></param> /// <returns></returns> public static Expression<Func<T, bool>> Or1<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) { //var param = first.Parameters[0]; var param = Expression.Parameter(typeof(T), "w");//指定引數和引數名稱 LambdaExpressionParameter lambdaExpression = new LambdaExpressionParameter(param); var left = lambdaExpression.Replace(first.Body); var right = lambdaExpression.Replace(second.Body); var body = Expression.Or(left, right); return Expression.Lambda<Func<T, bool>>(body, param); } /// <summary> /// Expression表示式樹lambda引數拼接--not /// </summary> /// <typeparam name="T"></typeparam> /// <param name="expression"></param> /// <returns></returns> public static Expression<Func<T, bool>> Not1<T>(this Expression<Func<T, bool>> expression) { var param = expression.Parameters[0];//指定引數和引數名稱 //var param = Expression.Parameter(typeof(T), "w"); var body = Expression.Not(expression.Body); return Expression.Lambda<Func<T, bool>>(body, param); } } #endregion
測試執行
namespace Test { public class Program { static void Main(string[] args) { List<int> grades1 = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; Expression<Func<int, bool>> expression = t => true; expression = expression.And1(t => t > 2); expression = expression.And1(t => t < 8); var ds = grades1.AsQueryable().Where(expression).ToList(); foreach (var item in ds) { Console.WriteLine($"IQueryable:{item}"); } Console.Read(); } } }