zoukankan      html  css  js  c++  java
  • 表达式目录树的应用

    1.使用表达式目录树实现两个不同类型的属性赋值:

    首先,准备两个实体类

        /// <summary>
        /// 实体类
        /// </summary>
        public class People
        {
            public int Age { get; set; }
            public string Name { get; set; }
            public int Id;
        }
        /// <summary>
        /// 实体类Target
        /// PeopleDTO
        /// </summary>
        public class PeopleCopy
        {
    
            public int Age { get; set; }
            public string Name { get; set; }
            public int Id;
        }

    接着写,数据处理类

      /// <summary>
        /// 生成表达式目录树  泛型缓存
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        public class ExpressionGenericMapper<TIn, TOut>//Mapper`2
        {
            private static Func<TIn, TOut> _FUNC = null;
            static ExpressionGenericMapper()
            {
                ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "p");
                List<MemberBinding> memberBindingList = new List<MemberBinding>();
                foreach (var item in typeof(TOut).GetProperties())
                {
                    MemberExpression property = Expression.Property(parameterExpression, typeof(TIn).GetProperty(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                foreach (var item in typeof(TOut).GetFields())
                {
                    MemberExpression property = Expression.Field(parameterExpression, typeof(TIn).GetField(item.Name));
                    MemberBinding memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
                Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
                {
                        parameterExpression
                });
                _FUNC = lambda.Compile();//拼装是一次性的
            }
            public static TOut Trans(TIn t)
            {
                return _FUNC(t);
            }
        }

    最后,程序中调用该代码处理

                        Stopwatch watch = new Stopwatch();
                        watch.Start();
                        for (int i = 0; i < 1_000_000; i++)
                        {
                            PeopleCopy peopleCopy = ExpressionGenericMapper<People, PeopleCopy>.Trans(people);
                        }
                        watch.Stop();
                        generic = watch.ElapsedMilliseconds;

    2. 使用表达式目录树,拼装sql语句

      internal static class SqlOperator
        {
            internal static string ToSqlOperator(this ExpressionType type)
            {
                switch (type)
                {
                    case (ExpressionType.AndAlso):
                    case (ExpressionType.And):
                        return "AND";
                    case (ExpressionType.OrElse):
                    case (ExpressionType.Or):
                        return "OR";
                    case (ExpressionType.Not):
                        return "NOT";
                    case (ExpressionType.NotEqual):
                        return "<>";
                    case ExpressionType.GreaterThan:
                        return ">";
                    case ExpressionType.GreaterThanOrEqual:
                        return ">=";
                    case ExpressionType.LessThan:
                        return "<";
                    case ExpressionType.LessThanOrEqual:
                        return "<=";
                    case (ExpressionType.Equal):
                        return "=";
                    default:
                        throw new Exception("不支持该方法");
                }
    
            }
        }
       public static class ExpressionExtension
        {
            public static void BatchDelete<T>(this IQueryable<T> entities, Expression<Func<T, bool>> expr)
            {
                ConditionBuilderVisitor visitor = new ConditionBuilderVisitor();
                visitor.Visit(expr);
                string condition = visitor.Condition();
    
                string sql = string.Format("DELETE FROM [{0}] WHERE {1};"
                    , typeof(T).Name//有可能还得根据泛型去获取
                    , condition);
                //然后执行sql
            }
    
        }

    3, 合并表达式

     /// <summary>
        /// 合并表达式 And Or  Not扩展
        /// </summary>
        public static class ExpressionExtend
        {
            /// <summary>
            /// 合并表达式 expr1 AND expr2
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="expr1"></param>
            /// <param name="expr2"></param>
            /// <returns></returns>
            public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
            {
                //return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters);
                if (expr1 == null)
                    return expr2;
                else if (expr2 == null)
                    return expr1;
                ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
                NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
                var left = visitor.Replace(expr1.Body);
                var right = visitor.Replace(expr2.Body);
                var body = Expression.And(left, right);
                return Expression.Lambda<Func<T, bool>>(body, newParameter);
            }
            /// <summary>
            /// 合并表达式 expr1 or expr2
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="expr1"></param>
            /// <param name="expr2"></param>
            /// <returns></returns>
            public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
            {
                if (expr1 == null)
                    return expr2;
                else if (expr2 == null)
                    return expr1;
                ParameterExpression newParameter = Expression.Parameter(typeof(T), "c");
                NewExpressionVisitor visitor = new NewExpressionVisitor(newParameter);
    
                var left = visitor.Replace(expr1.Body);
                var right = visitor.Replace(expr2.Body);
                var body = Expression.Or(left, right);
                return Expression.Lambda<Func<T, bool>>(body, newParameter);
            }
            public static Expression<Func<T, bool>> Not<T>(this Expression<Func<T, bool>> expr)
            {
                if (expr == null) return null;
                var candidateExpr = expr.Parameters[0];
                var body = Expression.Not(expr.Body);
    
                return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
            }
        }

    方法调用

                    Expression<Func<People, bool>> lambda1 = x => x.Age > 5;
                    Expression<Func<People, bool>> lambda2 = x => x.Id > 5;
                    
                    Expression<Func<People, bool>> lambda3 = lambda1.And(lambda2);
                    Expression<Func<People, bool>> lambda4 = lambda1.Or(lambda2);
                    Expression<Func<People, bool>> lambda5 = lambda1.Not();
                    Do1(lambda3);
                    Do1(lambda4);
                    Do1(lambda5);
  • 相关阅读:
    hello
    1234566i 还是规范
    萨嘎给
    DRF 商城项目
    DRF 商城项目
    DRF 商城项目
    Windows 上连接本地 Linux虚拟机上的 mysql 数据库
    xadmin 数据添加报错: IndexError: list index out of range
    python 实现聊天室
    xadmin 组件拓展自定义使用
  • 原文地址:https://www.cnblogs.com/for-easy-fast/p/12408483.html
Copyright © 2011-2022 走看看