將簡單的lambda表達式樹轉爲對應的sqlwhere條件

一、Lambda的介紹html

  園中已經有不少關於lambda的介紹了。簡單來說就是vs編譯器給我帶來的語法糖,本質來說仍是匿名函數。在開發中,lambda給咱們帶來了不少的簡便。關於lambda的演變過程能夠看 Lambda的演變過程git

  在這裏簡單的寫個lambda的寫法:github

  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());//輸出7sql

二、Lambda表達式樹:express

  System.Linq.Expressions命名空間中包含了表明表達式的各個類,這些類都是繼承於Expression這個類,能夠經過Expression這個類的靜態方法來構建一些表達式樹。。表達式樹由三部分組成,左邊、操做類型、右邊 這三部分組成。ide

  

  這樣就構成了一個簡單的表達式樹了。舉個栗子:函數

  咱們構建一個輸入一個int類型的參數,判斷它是否是大於10的lambda表達式數,那麼左邊的表達式樹就是這個int類型的參數,操做類型就是「大於」,右邊表達式樹就是常量10.spa

 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的表達式樹。code

  先分析下,htm

  第一步咱們要計算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表達式樹

  簡單的構建表達式樹就講到這裏了。

三、根據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

   若是有哪裏寫的不對的地方,還請指教,以避免我誤導了他人。

相關文章
相關標籤/搜索