我個人學習新技術有一個方法,如果遇到問題會根據以前的經驗來尋找一些類似的解決方法。有人會說,如果這個問題在你的學習或者工作生涯中都沒有遇到過呢?很簡單,通過搜索資料或查閱相關書籍學習別人的經驗。
在如今的每個商業應用開發過程中,基本上開發人員都會遇到一個問題,就是如何根據不同的條件構建查詢表達式或Sql查詢語句。根據之前的使用Hibernate或者JPA的開發經驗,自然想到,根據不同的條件判斷拼接Hql語句或者叫Jpql語句。但是,在使用EF6開發中遇到這種問題想手動的拼接Lambda查詢表達式,有點困難。幸好,通過搜索資料找到了國外高人的解決方案,通過PredicateBuilder實現EF6多條件動態查詢。
PredicateBuilder源碼
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public static class PredicateBuilder
{
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>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
PredicateBuilder其實是LINQKit的一部分,LINQKit是適用於LINQ to SQL和Entity Framework功能增強版拓展工具。
注:如果你在使用LINQ to SQL,你只要把PredicateBuilder加入你的項目即可。但是,如果你在使用Entity Framework框架,你將需要LINQKit提供的AsExpandable功能。所以必須得在你的項目中要么加入LINQKit.dll的引用要么直接拷貝LINQKit的源代碼進去。
如何使用PredicateBuilder
以實際項目中用戶的多條件查詢為例,詳細步驟如下:
1、把LINQKit.dll引用或者其源代碼加入項目中;
2、在DAL層使用AsExpandable方法查詢;
public IQueryable<T> LoadLinqKitEntities(Expression<Func<T, bool>> whereLambda) { return db.Set<T>().AsExpandable().Where(whereLambda).AsQueryable(); }
3、在BLL層根據傳遞的參數拼接動態的Lambda表達式。
internal IList<UserInfo> GetUsersByParam(UserInfo userInfo) { Expression<Func<UserInfo, bool>> eps = PredicateBuilder.True<UserInfo>(); if (userInfo.DepartmentId != null&&userInfo.DepartmentId>0) { eps = eps.And(u => u.DepartmentId == userInfo.DepartmentId); } if (userInfo.Name.Length > 0) { eps = eps.And(u => u.RealName.Contains(userInfo.Name)); } eps = eps.And(u => u.Name != "admin"); return efDal.LoadLinqKitEntities(eps).Select(u => u).ToList(); }
通過以上幾步就可以實現在EF6中動態的拼接Lambda表達式,支持動態查詢了,動手試試吧。
原創文章,轉載請注明: 轉載自追風箏的coder
本文鏈接地址: 使用PredicateBuilder實現EF6多條件動態查詢
http://vtocode.com/blog/index.php/2014/12/03/ef6-multi-condition-dynamic-query/