說明: 在我們日常代碼開發中很多的地方都用到了Lambda表達式進行過濾操作,我們很多優秀的ORM也是使用表達式來進行數據的查詢。但是對於一些複雜的過 濾單純的使用Lambda已經不能夠解決問題了那麼就需要表達式樹來進行條件的一個拼接。 下麵介紹一個本人寫的一個工具類有助於項目中更好的使用: 以上就 ...
說明: 在我們日常代碼開發中很多的地方都用到了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; } }
我們運行程式會輸出如下的內容:
以上只是針對如何使用表達式樹做個例子 如有不同的可以留言哦!