最近比較閑,年底了,項目也進入尾聲;每天就是維護一下系統,整理整理文檔,整理知識點,這樣才覺得有點意思;
問題
在使用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();
方法二有點啰嗦,當時是用表達式樹來創建的;大家可以用匿名表達式簡單一點。但是在合並表達式的邏輯是,重新更改了一下表達式一和表達式二的參數,這樣在編譯的時候就可以通過了。
寫的不咋樣,日日精進吧。。。。