Lambda expressions dynamic assembly query

Recently more leisure, by the end of the project coming to an end; it is to maintain the system every day, tidy up the document, organize knowledge, so that they feel a bit mean;

problem

When using where Linq's () queries, do not know is how dynamic assembly of multiple query, is how to do? I was doing this, consider the following codes;

method one:

1.1 Expression class extension

  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> ()); // a delegate or lambda expression to the expression list of parameters. 

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

1.2 instantiation code

            List <string> strList = new List <string> () { " Zhengzhou", "Shanghai hukou", "Lushan embrace pot dishes," "Nanjing pickled fish"}; 
            // traditional wording 
            Func <string, bool> func = (t) => t.Length> 3 && t.Contains ( " fish"); 
            var = listA strList.Where (FUNC) .ToList (); 
            // use extended wording 
            var = expression The PredicateExtensions.True <String> (); 
            expression The expression.And = (T => t.Length>. 3); 
            expression The expression.And = (T => t.Contains ( "fish")); 
            var expression.Compile the predicateA = (); 
            var listB strList.Where = ( predicate) .ToList ();

  

Method two: Merge two expressions Expression

2.1 Parameters expression extension class

    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 instantiation code

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 (); // compile the expression 
                var c_list = numbers.Where (c_result) .ToList  ();

Method Two little long-winded, was used to create the expression tree; we can use a little simple anonymous expression. But the logic of the merger expression is again a change a bit expressions and expressions two parameters, at compile time so you can pass.

Written not Zeyang, daily sophisticated bar. . . .

Guess you like

Origin www.cnblogs.com/searchbaidu/p/11937623.html