將不確定變為確定~表達(da)式樹是否可以有個集(ji)合,條件過濾(lv)有了(le)新(xin)(xin)方向續(新(xin)(xin)增了(le)OR和AND查詢)
今天(tian)發表了《將不(bu)確(que)定(ding)變為確(que)定(ding)~表達式樹是(shi)否可(ke)以(yi)有(you)個(ge)集合,條(tiao)件過(guo)濾有(you)了新方(fang)向(xiang)》文章后,馬(ma)上(shang)有(you)朋友問起(qi),如何實(shi)(shi)現(xian)OR查詢,如果(guo)實(shi)(shi)現(xian)AND查詢,事實(shi)(shi)上(shang)它說的可(ke)能并(bing)不(bu)完(wan)整(zheng),完(wan)整(zheng)的話應該是(shi),“如何實(shi)(shi)現(xian)N個(ge)字段(duan)進行OR運(yun)算和AND運(yun)算”呢,沒錯,我在那篇文章中,條(tiao)件過(guo)濾只(zhi)是(shi)針對單(dan)個(ge)字段(duan)的,是(shi)一種AND運(yun)算,也(ye)是(shi)一種條(tiao)件的過(guo)濾機(ji)制,即:
有條件a1,a2,a3,它的(de)過(guo)濾方式是先過(guo)濾a1,然后在剩下的(de)結果(guo)里過(guo)濾a2,最后再(zai)過(guo)濾a3,它相然等同于(yu)a1 && a2 && a3,但如(ru)果(guo)要實現OR運算,我(wo)的(de)那(nei)個程序就無能為力了,看(kan)(kan)看(kan)(kan)我(wo)們偉大(da)的(de)同志寫的(de)這(zhe)個OR與AND為表達式樹實現的(de)擴展方法吧,呵(he)呵(he) 。
1 /// <summary> 2 /// 條件(jian)建立者(zhe) 3 /// [單(dan)元表(biao)達(da)式(shi)主要考用用在數(shu)據(ju)庫(ku)字(zi)段(duan)或(huo)是其他集合字(zi)段(duan)中考用直接返回bool查詢的] 4 /// [考(kao)用考(kao)慮,如(ru)果一(yi)個內存(cun)集合中,考(kao)用定義一(yi)個屬性(xing),屬性(xing)中有(you)邏輯,例如(ru):return str.Lenght==1;這樣的可以用到(dao)單(dan)元運算符。] 5 /// </summary> 6 public static class PredicateBuilder 7 { 8 /// <summary> 9 /// 單元 true 表達式(shi) 10 /// </summary> 11 /// <typeparam name="T">指定泛型 T</typeparam> 12 /// <returns>true</returns> 13 public static Expression<Func<T, bool>> True<T>() 14 { 15 return item => true; 16 } 17 18 /// <summary> 19 /// 單元 false 表達式 20 /// </summary> 21 /// <typeparam name="T">指定泛型 T</typeparam> 22 /// <returns>false</returns> 23 public static Expression<Func<T, bool>> False<T>() 24 { 25 return item => false; 26 } 27 28 /// <summary> 29 /// 雙元(yuan) Or 表達式 30 /// </summary> 31 /// <typeparam name="T">指定泛型 T</typeparam> 32 /// <param name="exprleft">左表達式</param> 33 /// <param name="exprright">右表(biao)達式</param> 34 /// <returns>返回合并表達式</returns> 35 public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> exprleft, Expression<Func<T, bool>> exprright) 36 { 37 var invokedExpr = Expression.Invoke(exprright, exprleft.Parameters.Cast<Expression>()); 38 return Expression.Lambda<Func<T, bool>>(Expression.Or(exprleft.Body, invokedExpr), exprleft.Parameters); 39 } 40 41 /// <summary> 42 /// 雙元(yuan) And 表達(da)式(shi) 43 /// </summary> 44 /// <typeparam name="T">指定(ding)泛型(xing) T</typeparam> 45 /// <param name="exprleft">左表達式</param> 46 /// <param name="exprright">右表達式</param> 47 /// <returns>返回合并(bing)表達式</returns> 48 public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> exprleft, Expression<Func<T, bool>> exprright) 49 { 50 var invokedExpr = Expression.Invoke(exprright, exprleft.Parameters.Cast<Expression>()); 51 return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(exprleft.Body, invokedExpr), exprleft.Parameters); 52 } 53 }
再配合我的統(tong)一(yi)條件功(gong)能類,進行(xing)一(yi)下改造:
1 /// <summary> 2 /// 功能:條件(jian)過濾類 3 /// 作者:張占嶺 4 /// 日期(qi):2012-6-7 5 /// </summary> 6 public class PredicateList<TEntity> : IEnumerable<Expression<Func<TEntity, bool>>> where TEntity : class 7 { 8 List<Expression<Func<TEntity, bool>>> expressionList; 9 public PredicateList() 10 { 11 expressionList = new List<Expression<Func<TEntity, bool>>>(); 12 } 13 /// <summary> 14 /// 添加到集合 15 /// </summary> 16 /// <param name="predicate"></param> 17 public void Add(Expression<Func<TEntity, bool>> predicate) 18 { 19 expressionList.Add(predicate); 20 } 21 /// <summary> 22 /// Or操作添加到集合 23 /// </summary> 24 /// <param name="exprleft"></param> 25 /// <param name="exprright"></param> 26 public void AddForOr(Expression<Func<TEntity, bool>> exprleft, Expression<Func<TEntity, bool>> exprright) 27 { 28 expressionList.Add(exprleft.Or(exprright)); 29 } 30 /// <summary> 31 /// And操作添加到集合 32 /// </summary> 33 /// <param name="exprleft"></param> 34 /// <param name="exprright"></param> 35 public void AddForAnd(Expression<Func<TEntity, bool>> exprleft, Expression<Func<TEntity, bool>> exprright) 36 { 37 expressionList.Add(exprleft.And(exprright)); 38 } 39 40 #region IEnumerable 成員 41 42 public IEnumerator GetEnumerator() 43 { 44 return expressionList.GetEnumerator(); 45 } 46 47 #endregion 48 49 #region IEnumerable<Expression<Func<TEntity>>> 成員 50 51 IEnumerator<Expression<Func<TEntity, bool>>> IEnumerable<Expression<Func<TEntity, bool>>>.GetEnumerator() 52 { 53 return expressionList.GetEnumerator(); 54 } 55 56 #endregion 57 }
嘿嘿,這樣(yang)就可以把一些用到做AND或者OR的條件先進行組成,最(zui)后再和其它條件一起(qi)過濾(lv),就OK了(le),呵(he)呵(he)。
調用時,可以這樣:
1 PredicateList<UserBases> zzl = new PredicateList<UserBases>(); 2 Expression<Func<UserBases, bool>> exp_name = i => i.Name.Contains("zzl"); 3 Expression<Func<UserBases, bool>> exp_id = i => i.UserID == 1; 4 zzl.AddForOr(exp_name, exp_id); 5 GetModel(zzl).ForEach(i => Console.WriteLine(i.Name)); 6 Console.ReadKey();
OK,世界上(shang)對(dui)于(yu)i.Name和(he)i.UserID的(de)(de)賦值,是我(wo)們在業務上(shang)判(pan)斷過(guo)的(de)(de),在PredicateList中存在的(de)(de)過(guo)濾條件就是真實要被過(guo)濾的(de)(de)。