对象转lambda表达式

Posted 322829

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象转lambda表达式相关的知识,希望对你有一定的参考价值。

   /// <summary>
        ///  根据T 转换lambda 表达式
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <typeparam name="T"></typeparam>
        /// <param name="request"></param>

public static Expression<Func<T, bool>> GetLambdaByRequest<TRequest, T>(TRequest request) where T : class
       

            Expression<Func<T, bool>> where = ex => true;
            foreach (PropertyInfo info in typeof(TRequest).GetProperties())
           
                object value = info.GetValue(request, null);
                if (info.Name != "CurrentPage" && info.Name != "PageSize" && value != null && value.ToString() != "")
               

                    if (info.Name == "Title")
                   
                        where = where.And(LambdaUtil<T>.In(info.Name, value.ToString().Split(",")));
                   
                    else
                   
                        where = where.And(LambdaUtil<T>.Equal(info.Name, info.GetValue(request, null)));
                   
               
           
            return where;
       

/// <summary> 
    /// LambdaHelper  扩展
    /// </summary>
    public static class LambdaHelper
   
        /// <summary>
        /// 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)
       
            // 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);
       
        /// <summary>
        /// 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)
       
            return first.Compose(second, Expression.And);
       
        /// <summary>
        /// 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)
       
            return first.Compose(second, Expression.Or);
       
   
    /// <summary>
    /// 
    /// </summary>
    public class ParameterRebinder : ExpressionVisitor
   
        private readonly Dictionary<ParameterExpression, ParameterExpression> map;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
       
            this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
       
            return new ParameterRebinder(map).Visit(exp);
       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        protected override Expression VisitParameter(ParameterExpression p)
       
            ParameterExpression replacement;
            if (map.TryGetValue(p, out replacement))
           
                p = replacement;
           
            return base.VisitParameter(p);
       
   

 

 

 /// <summary>
    /// Lambda  表达式  基础类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public static class LambdaUtil<T>
   
        /// <summary>
        /// lambda表达式:t=>true
        /// </summary>
        /// <returns></returns>
        public static Expression<Func<T, bool>> True()
       
            return t => true;
       

        /// <summary>
        /// lambda表达式:t=>false
        /// </summary>
        /// <returns></returns>
        public static Expression<Func<T, bool>> False()
       
            return t => false;
       

        /// <summary>
        /// lambda表达式:t=>t.propName
        /// 多用于order排序
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <typeparam name="TKey">返回类型</typeparam>
        /// <param name="propName">属性名</param>
        /// <returns></returns>
        private static Expression<Func<T, TKey>> Order<TKey>(string propName)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个属性
            MemberExpression property = Expression.Property(parameter, propName);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, TKey>>(property, parameter);
       
        /// <summary>
        /// lambda表达式:t=>t.propName==propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Equal(string propName, object propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个相等比较Expression
            BinaryExpression binary = Expression.Equal(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       
        /// <summary>
        /// lambda表达式:t=>t.propName!=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotEqual(string propName, string propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.NotEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName&lt;propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> LessThan(string propName, string propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.LessThan(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName&lt;=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> LessThanOrEqual(string propName, string propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.LessThanOrEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName>propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> GreaterThan(string propName, string propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.GreaterThan(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName>=propValue
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> GreaterThanOrEqual(string propName, string propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue);
            // 创建一个不相等比较Expression
            BinaryExpression binary = Expression.GreaterThanOrEqual(member, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.contains(propvalue1) ||...||t.contains(propvalueN)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValues">属性值数组</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> In(string propName, string[] propValues)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t"); // left
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            Expression constant = Expression.Constant(false);
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] typeof(string) );
            foreach (string item in propValues)
           
                // 创建一个带参数方法Expression
                MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right
                // 连接参数方法
                constant = Expression.Or(methodCall, constant);
           

            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(constant, new ParameterExpression[] parameter );
       

        /// <summary>
        /// lambda表达式:t=>!(t.contains(propvalue1) ||...||t.contains(propvalueN))
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValues">属性值数组</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotIn(string propName, string[] propValues)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            Expression constant = Expression.Constant(false);
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] typeof(string) );
            foreach (string item in propValues)
           
                // 创建一个带参数方法Expression
                MethodCallExpression methodCall = Expression.Call(member, method, Expression.Constant(item)); // right
                // 连接参数方法
                constant = Expression.Or(methodCall, constant);
           

            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(Expression.Not(constant), new ParameterExpression[] parameter );
       

        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Contains(string propName, object propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] typeof(string) );
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> StartWith(string propName, object propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("StartsWith", new[] typeof(string) );
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
       

        /// <summary>
        /// lambda表达式:t=>t.propName.Contains(propValue)
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> EndsWith(string propName, object propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("EndsWith", new[] typeof(string) );
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(methodCall, parameter);
       

        /// <summary>
        /// lambda表达式:!(t=>t.propName.Contains(propValue))
        /// 多用于where条件
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="propName">属性名称</param>
        /// <param name="propValue">属性值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> NotContains(string propName, object propValue)
       
            // 创建节点参数t
            ParameterExpression parameter = Expression.Parameter(typeof(T), "t");
            // 创建一个成员(字段/属性)
            MemberExpression member = Expression.PropertyOrField(parameter, propName);
            // 创建一个常数
            ConstantExpression constant = Expression.Constant(propValue, typeof(string));
            // 创建一个方法
            MethodInfo method = typeof(string).GetMethod("Contains", new[] typeof(string) );
            // 创建一个带参数方法Expression
            MethodCallExpression methodCall = Expression.Call(member, method, constant);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(Expression.Not(methodCall), parameter);
       

        /// <summary>
        /// lambda表达式:t=>left and right
        /// 多用于where条件
        /// </summary>
        /// <param name="left">左侧条件</param>
        /// <param name="right">右侧条件</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
       
            // 创建参数表达式
            InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            // 创建and运算
            BinaryExpression binary = Expression.And(left.Body, invocation);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, left.Parameters);
       

        /// <summary>
        /// lambda表达式:t=>left or right
        /// 多用于where条件
        /// </summary>
        /// <param name="left">左侧条件</param>
        /// <param name="right">右侧条件</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or(Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
       
            // 创建参数表达式
            InvocationExpression invocation = Expression.Invoke(right, left.Parameters.Cast<Expression>());
            // 创建or运算
            BinaryExpression binary = Expression.Or(left.Body, invocation);
            // 生成lambda表达式
            return Expression.Lambda<Func<T, bool>>(binary, left.Parameters);
       
   

 

 

以上是关于对象转lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章

史上最全面的Java8教程玩转函数式接口

代码世界中的Lambda

java8 Lambda表达式的10个例子(转)

Java中Lambda表达式的使用(转)

[转] Java中Comparator进行对象排序

maven编译报错 -source 1.5 中不支持 lambda 表达式(转)