表达式树的说明与运用
程序员文章站
2022-06-05 19:24:00
说明: 在我们日常代码开发中很多的地方都用到了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; } }
我们运行程序会输出如下的内容:
以上只是针对如何使用表达式树做个例子 如有不同的可以留言哦!
上一篇: 历史上真的有丐帮吗?为何他们从未起义*?
下一篇: 30年竹叶青口感是怎样的