zoukankan      html  css  js  c++  java
  • 将简单的lambda表达式树转为对应的sqlwhere条件

    1、Lambda的介绍

      园中已经有很多关于lambda的介绍了。简单来讲就是vs编译器给我带来的语法糖,本质来讲还是匿名函数。在开发中,lambda给我们带来了很多的简便。关于lambda的演变过程可以看 Lambda的演变过程

      在这里简单的写个lambda的写法:

      Func<int, int, int> calculate = (x, y) => { return x + y; };//计算x+y的lambda
      Console.WriteLine(calculate(1, 2).ToString());//输出3
      Console.WriteLine(calculate(2, 5).ToString());//输出7

    2、Lambda表达式树:

      System.Linq.Expressions命名空间中包含了代表表达式的各个类,这些类都是继承于Expression这个类,可以通过Expression这个类的静态方法来构建一些表达式树。。表达式树由三部分组成,左边、操作类型、右边 这三部分组成。

      

      这样就构成了一个简单的表达式树了。举个栗子:

      我们构建一个输入一个int类型的参数,判断它是不是大于10的lambda表达式数,那么左边的表达式树就是这个int类型的参数,操作类型就是“大于”,右边表达式树就是常量10.

     ParameterExpression leftExpression = Expression.Parameter(typeof(int), "m");//int类型的,参数名称为m
                ConstantExpression rightExpression = Expression.Constant(10, typeof(int));//常量表达式树,10
                //进行左边是否大于右边的判断
                var binaryExpression =Expression.GreaterThan(leftExpression, rightExpression);
                Console.WriteLine(binaryExpression.ToString());
                var lambda =Expression.Lambda<Func<int,bool>>(binaryExpression, leftExpression).Compile();//构建成lambda表达式
                Console.WriteLine(lambda(5).ToString());
    构建一个判断值是否大于10的表达式树

      我们再来构建一个输入三个int类型的参数(a,b,c),先计算a+b,再判断的(a+b)的值是否大于c的表达式树。

      先分析下,

      第一步我们要计算a+b,那么就要先构建一个a+b的表达式树,在这步,左边表达式树是参数a,操作类型是“+”,右边表达式树是参数b。

      第二步,将(a+b)的值与c比较,那么左边表达式树就是第一步构建好的表达式树,操作类型是">"的比较,右边表达式数是参数c。

    ParameterExpression left1Expression= Expression.Parameter(typeof(int), "a");//int类型的,参数名称为a
                ParameterExpression right1Expression = Expression.Parameter(typeof(int), "b");//int类型的,参数名称为b
                var aAndbExpression = Expression.Add(left1Expression, right1Expression);//进行相加拼接
                ParameterExpression cExpression= Expression.Parameter(typeof(int), "c");//int类型的,参数名称为c
                var finallyExpression = Expression.GreaterThan(aAndbExpression, cExpression);
                Console.WriteLine(finallyExpression.ToString());
                var finallyLambda= Expression.Lambda<Func<int,int,int, bool>>(finallyExpression, left1Expression, right1Expression, cExpression).Compile();//构建成lambda表达式
                Console.WriteLine(finallyLambda(1, 6, 10).ToString());
    构建输入a,b,c,并判断a+b是否大于c的lambda表达式树

      简单的构建表达式树就讲到这里了。

    3、根据lambda表达式树生成对应sqlwhere条件

      先简单来拆分几个简单的lambda表达式树

        internal class User
        {
            public string Name { get; set; }
    
            public string Address { get; set; }
    
            public int Age { get; set; }
    
            public int Sex { get; set; }
    
            public bool IsDelete { get; set; }
    
            public DateTime? CreateTime { get; set; }
        }
    User类

      a、Expression<Func<User, bool>> expression2 = m => m.Age == 10 && m.Age == 1;

        这个表达式树就是先判断Age是否等于10,在判断Age是否等于1,然后再对其结果进行与运算。分解如下:

        1)、m.Age == 10:先是左边是a.Age,这是一个MemberExpression(字段或者属性表达式),表达式树操作类型是==比较,右边是10这个常量表达式树

        2)、与1类似

        3)、将1和2的结果进行与运算

      b、Expression<Func<User, bool>> expression2 = m => GetAge() ? m.Address == "" : m.Age == 1;

    private static bool GetAge()
            {
                return false;
            }
    获取条件的方法

        这个表达式树是先判断GetAge方法返回的结果是true还是false,true的话就在判断Address是否等于空,false就判断Age是否等于1

        1)、GetAge();条件表达式树()ConditionalExpression。

        2)、m.Address == "",条件表达式树判断为true执行的部分,

        3)、m.Age == 1;条件表达式树判断为false执行的部分,

      就简单的拆分这两个表达式树。

      根据表达式树生成对应的sqlWhere:

    int[] ages = new int[] { 1, 2, 5, 67 };
                Expression<Func<User, bool>> expression2 = m => (m.Age == 10 && m.Address.StartsWith("浙江") && m.Address.Contains("") && m.Address.EndsWith("")) || (m.Sex == 0 || "" == m.Address && ages.Contains(m.Age) && m.Age == ages[3]);
                //Expression<Func<User, bool>> expression2 = m => m.Address.TrimStart() == "11" && m.Name.TrimEnd() == "3434" && m.Age == 1 && m.IsDelete == true;
                //Expression<Func<User, bool>> expression2 = m => GetAge() ? m.Address == "" : m.Age == 1;
    
                //Expression<Func<User, bool>> expression2 = m => m.Age == 10 && m.Age == 1;
                SqlServerVisitor sqlVisitor = new SqlServerVisitor("A.");
                var sqlMember = sqlVisitor.GetSqlWhere(expression2.Body);
                Console.WriteLine(sqlMember.Item1);
                if (sqlMember.Item2 != null)
                {
                    foreach (var item in sqlMember.Item2)
                    {
                        Console.WriteLine($"{item?.ParameterName},{item?.Value}");
                    }
                }
    表达式树

     源码下载:https://github.com/yjqGitHub/ExpressionResolve.git

       如果有哪里写的不对的地方,还请指教,以免我误导了他人。

     

      

  • 相关阅读:
    Poj 1742 Coins(多重背包)
    Poj 2350 Above Average(精度控制)
    求二进制数中1的个数
    Poj 1659 Distance on Chessboard(国际象棋的走子规则)
    Poj 2411 Mondriaan's Dream(压缩矩阵DP)
    Poj 2136 Vertical Histogram(打印垂直直方图)
    Poj 1401 Factorial(计算N!尾数0的个数——质因数分解)
    poj 2390 Bank Interest(计算本利和)
    Poj 2533 Longest Ordered Subsequence(LIS)
    Poj 1887 Testing the CATCHER(LIS)
  • 原文地址:https://www.cnblogs.com/yjq-code/p/6913832.html
Copyright © 2011-2022 走看看