將不確定變為確定~表達式樹是否可以有個集合,條件過濾有了新方向續(新增了OR和AND查詢)


回到目錄

今天發表了《將不確定變為確定~表達式樹是否可以有個集合,條件過濾有了新方向》文章后,馬上有朋友問起,如何實現OR查詢,如果實現AND查詢,事實上它說的可能並不完整,完整的話應該是,“如何實現N個字段進行OR運算和AND運算”呢,沒錯,我在那篇文章中,條件過濾只是針對單個字段的,是一種AND運算,也是一種條件的過濾機制,即:

有條件a1,a2,a3,它的過濾方式是先過濾a1,然后在剩下的結果里過濾a2,最后再過濾a3,它相然等同於a1 && a2 && a3,但如果要實現OR運算,我的那個程序就無能為力了,看看我們偉大的JamesJim同志寫的這個OR與AND為表達式樹實現的擴展方法吧,呵呵 。

 1     /// <summary>
 2     /// 條件建立者
 3     /// [單元表達式主要考用用在數據庫字段或是其他集合字段中考用直接返回bool查詢的]
 4     /// [考用考慮,如果一個內存集合中,考用定義一個屬性,屬性中有邏輯,例如:return str.Lenght==1;這樣的可以用到單元運算符。]
 5     /// </summary>
 6     public static class PredicateBuilder
 7     {
 8         /// <summary>
 9         /// 單元 true 表達式
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         /// 雙元 Or 表達式
30         /// </summary>
31         /// <typeparam name="T">指定泛型 T</typeparam>
32         /// <param name="exprleft">左表達式</param>
33         /// <param name="exprright">右表達式</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         /// 雙元 And 表達式
43         /// </summary>
44         /// <typeparam name="T">指定泛型 T</typeparam>
45         /// <param name="exprleft">左表達式</param>
46         /// <param name="exprright">右表達式</param>
47         /// <returns>返回合並表達式</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     }

再配合我的統一條件功能類,進行一下改造:

 1     /// <summary>
 2     /// 功能:條件過濾類
 3     /// 作者:張占嶺
 4     /// 日期: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     }

嘿嘿,這樣就可以把一些用到做AND或者OR的條件先進行組成,最后再和其它條件一起過濾,就OK了,呵呵。

調用時,可以這樣:

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,世界上對於i.Name和i.UserID的賦值,是我們在業務上判斷過的,在PredicateList中存在的過濾條件就是真實要被過濾的。

回到目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM