技术学习

我所喜欢的

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
using Gate.ExpressionBuilder;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Fast.Framework
{
    public static class PredicateBuilder
    {
        /// <summary>
        /// 创建lambda表达式:p=>true
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <returns></returns>
        public static Expression<Func<T, bool>> True<T>()
        {
            return p => true;
        }

        /// <summary>
        /// 创建lambda表达式:p=>false
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <returns></returns>
        public static Expression<Func<T, bool>> False<T>()
        {
            return p => false;
        }

        /// <summary>
        ///     以 Expression.AndAlso 组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression<Func<T, bool>> And<T>(Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.AndAlso);
        }

        /// <summary>
        ///     以 Expression.OrElse 组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <returns>组合后的表达式</returns>
        public static Expression<Func<T, bool>> Or<T>(Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.OrElse);
        }


        #region 表达式组合辅助方法

        /// <summary>
        ///     以特定的条件运行组合两个Expression表达式
        /// </summary>
        /// <typeparam name="T">表达式的主实体类型</typeparam>
        /// <param name="first">第一个Expression表达式</param>
        /// <param name="second">要组合的Expression表达式</param>
        /// <param name="merge">组合条件运算方式</param>
        /// <returns>组合后的表达式</returns>
        private static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
            Func<Expression, Expression, Expression> merge)
        {
            var map =
                first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
            return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }


        #endregion



        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="TKey">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <returns></returns>
        public static Expression<Func<T, TKey>> GetOrderExpression<T, TKey>(string propertyName)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            return Expression.Lambda<Func<T, TKey>>(Expression.Property(parameter, propertyName), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName == propertyValue
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateEqual<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.Equal(member, constant), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName != propertyValue
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateNotEqual<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.NotEqual(member, constant), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName > propertyValue
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateGreaterThan<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.GreaterThan(member, constant), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>  propertyValue > p.propertyName 
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateLessThan<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.LessThan(member, constant), parameter);

            
        }

        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName >= propertyValue
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateGreaterThanOrEqual<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.GreaterThanOrEqual(member, constant), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>propertyValue >= p.propertyName 
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <typeparam name="S">参数类型</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateLessThanOrEqual<T, S>(string propertyName, S propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");//创建参数p
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(S));//创建常数
            return Expression.Lambda<Func<T, bool>>(Expression.LessThanOrEqual(member, constant), parameter);
        }

        /// <summary>
        /// 创建lambda表达式:p=>p.propertyName.Contains(propertyValue)
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateContains<T>(string propertyName, string propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
            return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <param name="propVals"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateIn<T>(string propertyName, List<string> propVals)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            MethodInfo method = typeof(List<string>).GetMethod("Contains", new[] { typeof(string) });
            ConstantExpression constant = Expression.Constant(propVals, typeof(List<string>));
            return Expression.Lambda<Func<T, bool>>(Expression.Call(constant, method, member), parameter);
            //return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
        }

        public static Expression<Func<T, bool>> CreateIn<T>(string propertyName, string[] propVals)
        {
            List<string> pVals = propVals.ToList();
            return CreateIn<T>(propertyName, pVals);
        }

        public static Expression<Func<T, bool>> CreateIn<T>(string propertyName, List<int> propVals)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            MethodInfo method = typeof(List<int>).GetMethod("Contains", new[] { typeof(int) });
            ConstantExpression constant = Expression.Constant(propVals, typeof(List<int>));
            return Expression.Lambda<Func<T, bool>>(Expression.Call(constant, method, member), parameter);
            //return Expression.Lambda<Func<T, bool>>(Expression.Call(member, method, constant), parameter);
        }

        public static Expression<Func<T, bool>> CreateIn<T>(string propertyName, int[] propVals)
        {
            List<int> pVals = propVals.ToList();
            return CreateIn<T>(propertyName, pVals);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="propertyName"></param>
        /// <param name="propVals"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateBetween<T>(string propertyName, DateTime[] propVals)
        {
            if (propVals.Length < 2)
            {
                throw new ArgumentException("CreateBetween[ parameter propVals  need two values]");
            }
            var lowBound = CreateGreaterThanOrEqual<T,DateTime>(propertyName, propVals[0]);
            var upBound = CreateLessThanOrEqual<T, DateTime>(propertyName, propVals[1]);
            return And<T>(lowBound, upBound);
        }

        


        /// <summary>
        /// 创建lambda表达式:!(p=>p.propertyName.Contains(propertyValue))
        /// </summary>
        /// <typeparam name="T">对象名称(类名)</typeparam>
        /// <param name="propertyName">字段名称(数据库中字段名称)</param>
        /// <param name="propertyValue">数据值</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> CreateNotContains<T>(string propertyName, string propertyValue)
        {
            ParameterExpression parameter = Expression.Parameter(typeof(T), "p");
            MemberExpression member = Expression.PropertyOrField(parameter, propertyName);
            MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            ConstantExpression constant = Expression.Constant(propertyValue, typeof(string));
            return Expression.Lambda<Func<T, bool>>(Expression.Not(Expression.Call(member, method, constant)), parameter);
        }


    }
}

  

posted on 2023-12-28 11:02  飘扬De黑夜  阅读(55)  评论(0编辑  收藏  举报