表達式樹的說明與運用


說明: 在日常代碼開發中很多的地方都用到了Lambda表達式進行過濾操作,很多優秀的ORM也是使用表達式來進行數據的查詢。但是對於一些復雜的過 濾單純的使用Lambda已經不能夠解決問題了那么就需要表達式樹來進行條件的一個拼接。 

下面介紹一個本人寫的一個工具類有助於項目中更好的使用:

  1   public static class ExpressionTreeTools
  2     {
  3         /// <summary>
  4         /// 相當於&&操作
  5         /// ——just0ne
  6         /// </summary>
  7         /// <param name="thisFilter">已生成的過濾條件</param>
  8         /// <param name="otherFilter">未生成的過濾條件</param>
  9         /// <returns>新的過濾</returns>
 10         public static Expression And(this Expression thisFilter, Expression otherFilter)
 11         {
 12             return Expression.AndAlso(thisFilter, otherFilter);
 13         }
 14         /// <summary>
 15         /// 相當於||操作
 16         /// ——just0ne
 17         /// </summary>
 18         /// <param name="thisFilter">已生成的過濾條件</param>
 19         /// <param name="otherFilter">未生成的過濾條件</param>
 20         /// <returns>新的過濾</returns>
 21         public static Expression Or(this Expression thisFilter, Expression otherFilter)
 22         {
 23             return Expression.OrElse(thisFilter, otherFilter);
 24         }
 25         /// <summary>
 26         /// 相當於==操作
 27         /// ——just0ne
 28         /// </summary>
 29         /// <param name="thisParameterExpression">查詢對象</param>
 30         /// <param name="propertieName">屬性名稱</param>
 31         /// <param name="propertieValue">屬性值</param>
 32         /// <returns>新的過濾</returns>
 33         public static Expression GotoEqual(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 34         {
 35             return Expression.Equal(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue));
 36         }
 37         /// <summary>
 38         /// 相當於>=操作
 39         /// ——just0ne
 40         /// </summary>
 41         /// <param name="thisParameterExpression">查詢對象</param>
 42         /// <param name="propertieName">屬性名稱</param>
 43         /// <param name="propertieValue">屬性值</param>
 44         /// <returns>新的過濾</returns>
 45         public static Expression GotoGreaterThanOrEqual<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 46         {
 47             //大於或等於
 48             return Expression.GreaterThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 49         }
 50         /// <summary>
 51         /// 相當於小於等於操作
 52         /// ——just0ne
 53         /// </summary>
 54         /// <param name="thisParameterExpression">查詢對象</param>
 55         /// <param name="propertieName">屬性名稱</param>
 56         /// <param name="propertieValue">屬性值</param>
 57         /// <returns>新的過濾</returns>
 58         public static Expression GotoLessThanOrEqual<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 59         {
 60             //小於或等於
 61             return Expression.LessThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 62         }
 63         /// <summary>
 64         /// 相當於>操作
 65         /// ——just0ne
 66         /// </summary>
 67         /// <param name="thisParameterExpression">查詢對象</param>
 68         /// <param name="propertieName">屬性名稱</param>
 69         /// <param name="propertieValue">屬性值</param>
 70         /// <returns>新的過濾</returns>
 71         public static Expression GotoGreaterThan<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 72         {
 73             //大於
 74             return Expression.GreaterThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 75         }
 76         /// <summary>
 77         /// 相當於小於操作
 78         /// ——just0ne
 79         /// </summary>
 80         /// <param name="thisParameterExpression">查詢對象</param>
 81         /// <param name="propertieName">屬性名稱</param>
 82         /// <param name="propertieValue">屬性值</param>
 83         /// <returns>新的過濾</returns>
 84         public static Expression GotoLessThan<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 85         {
 86             //小於
 87             return Expression.LessThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 88         }
 89         /// <summary>
 90         /// 相當於>=操作
 91         /// ——just0ne
 92         /// </summary>
 93         /// <param name="thisParameterExpression">查詢對象</param>
 94         /// <param name="propertieName">屬性名稱</param>
 95         /// <param name="propertieValue">屬性值</param>
 96         /// <returns>新的過濾</returns>
 97         public static Expression GotoGreaterThanOrEqualByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 98         {
 99             //大於或等於
100             return Expression.GreaterThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
101         }
102         /// <summary>
103         /// 相當於小於或等於操作
104         /// ——just0ne
105         /// </summary>
106         /// <param name="thisParameterExpression">查詢對象</param>
107         /// <param name="propertieName">屬性名稱</param>
108         /// <param name="propertieValue">屬性值</param>
109         /// <returns>新的過濾</returns>
110         public static Expression GotoLessThanOrEqualByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
111         {
112             //小於或等於
113             return Expression.LessThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
114         }
115         /// <summary>
116         /// 相當於>操作
117         /// ——just0ne
118         /// </summary>
119         /// <param name="thisParameterExpression">查詢對象</param>
120         /// <param name="propertieName">屬性名稱</param>
121         /// <param name="propertieValue">屬性值</param>
122         /// <returns>新的過濾</returns>
123         public static Expression GotoGreaterThanByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
124         {
125             //大於
126             return Expression.GreaterThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
127         }
128         /// <summary>
129         /// 相當於小於操作
130         /// —一just0ne
131         /// </summary>
132         /// <param name="thisParameterExpression">查詢對象</param>
133         /// <param name="propertieName">屬性名稱</param>
134         /// <param name="propertieValue">屬性值</param>
135         /// <returns>新的過濾</returns>
136         public static Expression GotoLessThanByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
137         {
138             //小於
139             return Expression.LessThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
140         }
141 
142         /// <summary>
143         /// 一一just0ne
144         /// 包含操作 相當余 a=> arr.Contains(a.ID)
145         /// 如果arr中數據量過大則不適用linq
146         /// </summary>
147         /// <param name="thisParameterExpression">查詢對象</param>
148         /// <param name="propertieName">屬性名稱</param>
149         /// <param name="propertieValue">屬性值</param>
150         /// <returns>新的過濾</returns>
151         public static Expression ContainsOperations(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
152         {
153             MethodInfo method = null;
154             MemberExpression member = Expression.Property(thisParameterExpression, propertieName);
155             var containsMethods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => m.Name == "Contains");
156             foreach (var m in containsMethods)
157             {
158                 if (m.GetParameters().Count() == 2)
159                 {
160                     method = m;
161                     break;
162                 }
163             }
164             method = method.MakeGenericMethod(member.Type);
165             var exprContains = Expression.Call(method, new Expression[] { Expression.Constant(propertieValue), member });
166             return exprContains;
167         }
168 
169         /// <summary>
170         /// 一一just0ne
171         /// 包含操作 相當於  a=>a.ID.Contains(key)
172         /// </summary>
173         /// <param name="thisParameterExpression">查詢對象</param>
174         /// <param name="propertieName">屬性名稱</param>
175         /// <param name="propertieValue">屬性值</param>
176         /// <returns>新的過濾</returns>
177         public static Expression Contains(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
178         {
179             var propertyExp = Expression.Property(thisParameterExpression, propertieName);
180             MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
181             var someValue = Expression.Constant(propertieValue, typeof(string));
182             var containsMethodExp = Expression.Call(propertyExp, method, someValue);
183             return containsMethodExp;
184         }
185 
186     }

以上就是一些基本的拼接都有了接下來是如何進行使用 還是貼上代碼進行說明

  class Program
    {
        static void Main(string[] args)
        {
            string[] nameArr = new string[] { "just0ne", "kphui", "point" };
            var userDataList = GetUserDataList().AsQueryable();
            //初始化
            var parameterExpression = Expression.Parameter(typeof(UserData));
            var filter = (Expression)Expression.Constant(true);
            //尋找年歲大於10
            filter = filter.And(parameterExpression.GotoGreaterThan<int>("Age", 10));
            string key = Console.ReadLine();
            if (!String.IsNullOrEmpty(key))
            {
                var keyFilter = (Expression)Expression.Constant(false);
                keyFilter = keyFilter.Or(parameterExpression.Contains("Name", key));
                keyFilter = keyFilter.Or(parameterExpression.Contains("Phone", key));
                filter = filter.And(keyFilter);
            }
            filter = filter.And(parameterExpression.ContainsOperations("Name", nameArr));
            var lamadaFilter = Expression.Lambda<Func<UserData, bool>>(filter, parameterExpression);
            var userDatas = userDataList.Where(lamadaFilter).ToList();
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(userDatas));
        }

        public static List<UserData> GetUserDataList()
        {
            return new List<UserData>()
            {
                new UserData(){ Age=18, Id=1, Name="just0ne", Phone="13856****26" },
                new UserData(){ Age=22, Id=2, Name="point", Phone="17521****52" },
                new UserData(){ Age=21, Id=3, Name="geekdog", Phone="15562****36" },
                new UserData(){ Age=14, Id=4, Name="kphui" , Phone="13577****26"},
                new UserData(){ Age=13, Id=5, Name="lg" , Phone="13456****26"},
                new UserData(){ Age=16, Id=6, Name="ming", Phone="13356****26" },
                new UserData(){ Age=18, Id=7, Name="tencent", Phone="13256****26" },
                new UserData(){ Age=10, Id=8, Name="justin" , Phone="13156****26"},
                new UserData(){ Age=31, Id=9, Name="hujw", Phone="13823****26" },
                new UserData(){ Age=27, Id=10, Name="lqm" , Phone="13876****26"},
                new UserData(){ Age=26, Id=11, Name="jiujiu" , Phone="13846****26"},
            };
        }
    }

    public class UserData
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Phone { get; set; }

        public string Email { get; set; }

        public int Age { get; set; }
    }

 

運行程序會輸出如下的內容:

以上只是針對如何使用表達式樹做個例子 如有不同的可以留言哦!

 


免責聲明!

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



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