当前位置:
首页 > temp > 简明python教程 >
-
动态构造任意复杂的 Linq Where 表达式(2)
//如果实体属性名称和前端名称不一致,或者属性是一个自定义类型,需要继续访问其内部属性,使用点号分隔
93 if (propertyMap?.ContainsKey(rule.Field) == true)
94 {
95 names = propertyMap[rule.Field].Split('.', StringSplitOptions.RemoveEmptyEntries);
96 l = Expression.Property(parameter, names[0]);
97 foreach (var name in names.Skip(1))
98 {
99 l = Expression.Property(l, name);
100 }
101 }
102 else
103 {
104 l = Expression.Property(parameter, rule.PascalField);
105 }
106
107 Expression r = null; //值表达式
108 Expression e; //返回bool的各种比较表达式
109
110 //属于和不属于比较是多值比较,需要调用Contains方法,而不是调用比较操作符
111 //为空和不为空的右值为常量null,不需要构造
112 var specialRuleOps = SpecialRuleOps;
113
114 var isNullable = false;
115 var pt = typeof(T);
116 if(names != null)
117 {
118 foreach(var name in names)
119 {
120 pt = pt.GetProperty(name).PropertyType;
121 }
122 }
123 else
124 {
125 pt = pt.GetProperty(rule.PascalField).PropertyType;
126 }
127
128 //如果属性类型是可空值类型,取出内部类型
129 if (pt.IsDerivedFrom(typeof(Nullable<>)))
130 {
131 isNullable = true;
132 pt = pt.GenericTypeArguments[0];
133 }
134
135 //根据属性类型创建要比较的常量值表达式(也就是r)
136 if (!specialRuleOps.Contains(rule.Op))
137 {
138 switch (pt)
139 {
140 case Type ct when ct == typeof(bool):
141 r = BuildConstantExpression(rule, bool.Parse);
142 break;
143
144 #region 文字
145
146 case Type ct when ct == typeof(char):
147 r = BuildConstantExpression(rule, str => str[0]);
148 break;
149 case Type ct when ct == typeof(string):
150 r = BuildConstantExpression(rule, str => str);
151 break;
152
153 #endregion
154
155 #region 有符号整数
156
157 case Type ct when ct == typeof(sbyte):
158 r = BuildConstantExpression(rule, sbyte.Parse);
159 break;
160 case Type ct when ct == typeof(short):
161 r = BuildConstantExpression(rule, short.Parse);
162 break;
163 case Type ct when ct == typeof(int):
164 r = BuildConstantExpression(rule, int.Parse);
165 break;
166 case Type ct when ct == typeof(long):
167 r = BuildConstantExpression(rule, long.Parse);
168 break;
169
170 #endregion
171
172 #region 无符号整数
173
174 case Type ct when ct == typeof(byte):
175 r = BuildConstantExpression(rule, byte.Parse);
176 break;
177 case Type ct when ct == typeof(ushort):
178 r = BuildConstantExpression(rule, ushort.Parse);
179 break;
180 case Type ct when ct == typeof(uint):
181 r = BuildConstantExpression(rule, uint.Parse);
182 break;
183 case Type ct when ct == typeof(ulong):
184 r = BuildConstantExpression(rule, ulong.Parse);
185 break;
186
187 #endregion
188
189 #region 小数
190
191 case Type ct when ct == typeof(float):
192 r = BuildConstantExpression(rule, float.Parse);
193 break;
194 case Type ct when ct == typeof(double):
195 r = BuildConstantExpression(rule, double.Parse);
196 break;
197 case Type ct when ct == typeof(decimal):
198 r = BuildConstantExpression(rule, decimal.Parse);
199 break;
200
201 #endregion
202
203 #region 其它常用类型
204
205 case Type ct when ct == typeof(DateTime):
206 r = BuildConstantExpression(rule, DateTime.Parse);
207 break;
208 case Type ct when ct == typeof(DateTimeOffset):
209 r = BuildConstantExpression(rule, DateTimeOffset.Parse);
210 break;
211 case Type ct when ct == typeof(Guid):
212 r = BuildConstantExpression(rule, Guid.Parse);
213 break;
214 case Type ct when ct.IsEnum:
215 r = Expression.Constant(rule.Data.ToEnumObject(ct));
216 break;
217
218 #endregion
219
220 default:
221 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的数据表达式");
222 }
223 }
224
225 if (r != null && pt.IsValueType && isNullable)
226 {
227 var gt = typeof(Nullable<>).MakeGenericType(pt);
228 r = Expression.Convert(r, gt);
229 }
230
231 switch (rule.Op)
232 {
233 case "eq": //等于
234 e = Expression.Equal(l, r);
235 break;
236 case "ne": //不等于
237 e = Expression.NotEqual(l, r);
238 break;
239 case "lt": //小于
240 e = Expression.LessThan(l, r);
241 break;
242 case "le": //小于等于
243 e = Expression.LessThanOrEqual(l, r);
244 break;
245 case "gt": //大于
246 e = Expression.GreaterThan(l, r);
247 break;
248 case "ge": //大于等于
249 e = Expression.GreaterThanOrEqual(l, r);
250 break;
251 case "bw": //开头是(字符串)
252 if (pt == typeof(string))
253 {
254 e = Expression.Call(l, pt.GetMethod(nameof(string.StartsWith), new[] {typeof(string)}), r);
255 }
256 else
257 {
258 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的开始于表达式");
259 }
260
261 break;
262 case "bn": //开头不是(字符串)
263 if (pt == typeof(string))
264 {
265 e = Expression.Not(Expression.Call(l, pt.GetMethod(nameof(string.StartsWith), new[] {typeof(string)}), r));
266 }
267 else
268 {
269 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的不开始于表达式");
270 }
271
272 break;
273 case "ew": //结尾是(字符串)
274 if (pt == typeof(string))
275 {
276 e = Expression.Call(l, pt.GetMethod(nameof(string.EndsWith), new[] {typeof(string)}), r);
277 }
278 else
279 {
280 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的结束于表达式");
281 }
282
283 break;
284 case "en": //结尾不是(字符串)
285 if (pt == typeof(string))
286 {
287 e = Expression.Not(Expression.Call(l, pt.GetMethod(nameof(string.EndsWith), new[] {typeof(string)}), r));
288 }
289 else
290 {
291 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的不结束于表达式");
292 }
293
294 break;
295 case "cn": //包含(字符串)
296 if (pt == typeof(string))
297 {
298 e = Expression.Call(l, pt.GetMethod(nameof(string.Contains), new[] {typeof(string)}), r);
299 }
300 else
301 {
302 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的包含表达式");
303 }
304
305 break;
306 case "nc": //不包含(字符串)
307 if (pt == typeof(string))
308 {
309 e = Expression.Not(Expression.Call(l, pt.GetMethod(nameof(string.Contains), new[] {typeof(string)}), r));
310 }
311 else
312 {
313 throw new InvalidOperationException($"不支持创建{pt.FullName}类型的包含表达式");
314 }
315
316 break;
317 case "in": //属于(是候选值列表之一)
318 e = BuildContainsExpression(rule, l, pt);
319 break;
320 case "
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数