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. . . .