Lambda表達式動態組裝查詢條件


最近比較閑,年底了,項目也進入尾聲;每天就是維護一下系統,整理整理文檔,整理知識點,這樣才覺得有點意思;

問題

在使用Linq的where()查詢的時候,不知道大家是怎么動態組裝多個查詢條件時,是怎么做的?我是這樣做的,請看下面代碼;

方法一:

1.1 Expression的擴展類

  public static class PredicateExtensions
  {
      public static Expression<Func<T, bool>> True<T>() { return f => true; }
  
      public static Expression<Func<T, bool>> False<T>() { return f => false; }
 
     public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)
     {
         var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
 
         return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters);
     }
 
     public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)
     {
         
         var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());//將一個委托或lambda表達式應用於參數表達式列表。

         return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
     }
 }

1.2 實例化代碼

            List<string> strList = new List<string>() { "鄭州","上海戶口", "魯山攬鍋菜", "南京酸菜魚" };
            //傳統寫法
            Func<string, bool> func = (t) => t.Length > 3&&t.Contains("魚");
            var listA=strList.Where(func).ToList();
            //使用擴展寫法
            var expression=PredicateExtensions.True<string>();
            expression = expression.And(t => t.Length > 3);
            expression = expression.And(t => t.Contains("魚"));
            var predicate = expression.Compile();
            var listB = strList.Where(predicate).ToList();

  

方法二:合並兩個Expression表達式

2.1 表達式參數擴展類

    public class MyExpressionVisitor:ExpressionVisitor
    {
        private readonly ParameterExpression _parameter;

        public MyExpressionVisitor(ParameterExpression parameter)
        {
            _parameter = parameter;
        }

        public ParameterExpression Parameter
        {
            get { return _parameter; }
        }


        public Expression Nodify(Expression exp)
        {
            Expression e = this.Visit(exp);
            return e;
        }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            return _parameter;
        }

    }

 2.2 實例化代碼

int[] numbers = { 19, 25, 6, 8, 49, 7, 8, 0, 1, 47, 35, 30,29 };
                //表達式一
                ParameterExpression leftPara = Expression.Parameter(typeof(int), "n");
                Expression a_con = Expression.Constant(13);
                BinaryExpression a_binary = Expression.GreaterThan(leftPara, a_con);
                var a_lambda = Expression.Lambda<Func<int, bool>>(a_binary,leftPara);
                var a_result = a_lambda.Compile();
                var a_list = numbers.Where(a_result).ToList();
                //表達式二
                ParameterExpression b_leftPara = Expression.Parameter(typeof(int), "n");
                Expression b_con = Expression.Constant(30);
                BinaryExpression b_binary = Expression.LessThanOrEqual(b_leftPara, b_con);
                var b_lambda = Expression.Lambda<Func<int, bool>>(b_binary, b_leftPara);
                var b_result = b_lambda.Compile();
                var b_list = numbers.Where(b_result).ToList();


                //合並兩個表達式
                var vistor = new MyExpressionVisitor(leftPara);
                Expression c_1 = vistor.Nodify(a_lambda.Body);
                Expression c_2 = vistor.Nodify(b_lambda.Body);
                BinaryExpression c_binary = Expression.AndAlso(c_1, c_2);
                var c_lambda = Expression.Lambda<Func<int, bool>>(c_binary, leftPara);
                var c_result = c_lambda.Compile();//編譯表達式
                var c_list = numbers.Where(c_result).ToList(); 

方法二有點啰嗦,當時是用表達式樹來創建的;大家可以用匿名表達式簡單一點。但是在合並表達式的邏輯是,重新更改了一下表達式一和表達式二的參數,這樣在編譯的時候就可以通過了。

寫的不咋樣,日日精進吧。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM