自动生成 Lambda查询和排序,从些查询列表so easy

如下图查询页面,跟据不同条件动态生成lambda的Where条件和OrderBy,如果要增加或调整查询,只用改前台HTML即可,不用改后台代码

前台代码:

 1     <div style="padding-bottom: 5px;" id="queryForm">
 2
 3         <span>员工姓名:</span><input type="text" emptytext="ddd" data-options="{match:‘in‘}" class="mini-textbox" id="Age" />
 4         <span>部门:</span><input type="text" class="mini-textbox" data-options="{match:‘like‘}" id="Sex" />
 5
 6         生日从  <input id="beg" format="yyyy-MM-dd" showokbutton="false" showclearbutton="true" data-options="{match:‘from‘,innerkey:‘Birthday‘}" class="mini-datepicker" />
 7         至  <input id="end" format="yyyy-MM-dd" showokbutton="false" showclearbutton="true" data-options="{match:‘to‘,innerkey:‘Birthday‘}" class="mini-datepicker" />
 8
 9         <span>年龄从:</span><input type="text" emptytext="ddd" data-options="{match:‘from‘,innerkey:‘Age‘}" class="mini-textbox" id="bb" />
10         <span>至:</span><input type="text" class="mini-textbox" data-options="{match:‘to‘,innerkey:‘Age‘}" id="bd" />
11
12         <a class="mini-button" iconcls="icon-search" onclick="search()">查找</a>
13
14
15     </div>
16
17
18 <div id="datagrid1" ondrawcell="Link" onupdate="load" class="mini-datagrid" style="width: 100%; height: 100%;" allowresize="true"
19              idfield="Id" sortfield="Age" showpager="false" pagesize="-1" sizelist="[-1]" sortorder="asc" multiselect="true">
20             <div property="columns">
21                 <!--<div type="indexcolumn"></div>        -->
22                 <div type="checkcolumn"></div>
23                 <div field="UserName" data-options="{Func:‘test‘}" width="120" headeralign="center" allowsort="true">姓名</div>
24                 <div field="Sex" renderer="SexShow" width="120" headeralign="center" allowsort="true">性别</div>
25
26                 <div field="LoginName" width="120">登录名</div>
27                 <div field="Password" width="120">密码</div>
28                 <div field="Birthday" width="100">生日</div>
29                 <div field="Age" width="100" allowsort="true">年龄</div>
30                 <div field="Remark" align="right" width="100">备注</div>
31
32
33                 <div field="Married" renderer="MarriedShow" width="100">婚否</div>
34
35             </div>
36         </div>

查询控件上的 data-options="{match:‘from‘,innerkey:‘Birthday‘}" 后多个查询条件会组合成一个json数组,传到后台,反序列化成List<QueryItem>,排序条件Jquery 的Grid控件也会传到后台的,反序列化成SortItem,分页信息 反序列化成 Pager,详见后台代码。

上后台代码:比较复杂

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using App.Core;
  7 using System.Reflection;
  8 using System.Linq.Expressions;
  9 using System.Data.Entity;
 10 using System.Collections.Specialized;
 11 namespace App.PageBase.Query
 12 {
 13     //查询条件模型
 14     public class QueryItem
 15     {
 16         public string match { get; set; }
 17         public string value { get; set; }
 18         public string key { get; set; }
 19         public string innerkey { get; set; }
 20
 21     }
 22     //排序模型
 23     public class SortItem
 24     {
 25
 26         public string sortField { get; set; }
 27         public string sortOrder { get; set; }
 28     }
 29     //列表分页模型
 30     public class Pager
 31     {
 32         public int pageSize
 33         {
 34             get;
 35             set;
 36         }
 37         public int pageIndex
 38         {
 39             get;
 40             set;
 41         }
 42         public int totalCount
 43         {
 44             get;
 45             set;
 46         }
 47
 48     }
 49
 50
 51     //生成查询条件类
 52     public class QueryBulider<TEntity> where TEntity : class,new()
 53     {
 54         private Pager _pager;// = new Pager();
 55         private SortItem _sort;// = new SortItem();
 56         private List<QueryItem> _queryItems;//= new List<QueryItem>();
 57         public Pager pager
 58         {
 59             get { return _pager; }
 60             set { _pager = value; }
 61         }
 62         public SortItem sort
 63         {
 64             get { return _sort; }
 65             set { _sort = value; }
 66         }
 67         public List<QueryItem> queryItems
 68         {
 69             get { return _queryItems; }
 70             set { _queryItems = value; }
 71         }
 72         /// <summary>
 73         /// 根据 分页模型,排序模型,查询条件模型列表构造 自动查询生成器
 74         /// </summary>
 75         /// <param name="pager"></param>
 76         /// <param name="sort"></param>
 77         /// <param name="queryItems"></param>
 78         public QueryBulider(Pager pager, SortItem sort, List<QueryItem> queryItems)
 79         {
 80             this.pager = pager;
 81             this.sort = sort;
 82             this.queryItems = queryItems;
 83
 84
 85         }
 86         public QueryBulider()
 87         { }
 88
 89         /// <summary>
 90         /// 根据HTTP实例化
 91         /// </summary>
 92         /// <param name="requstForm"></param>
 93         public QueryBulider(NameValueCollection requstForm)
 94         {
 95             string filter = requstForm["filter"];
 96             string pageIndex = requstForm["pageIndex"];
 97             string pageSize = requstForm["pageSize"];
 98             string sortField = requstForm["sortField"];
 99             string sortOrder = requstForm["sortOrder"];
100
101             if (!string.IsNullOrEmpty(pageSize) && !string.IsNullOrEmpty(pageIndex)&&pageSize!="-1")
102             {
103                 this.pager = new Pager { pageIndex = int.Parse( pageIndex), pageSize = int.Parse( pageSize) };
104             }
105             if (!string.IsNullOrEmpty(sortField))
106             {
107                 this.sort = new SortItem { sortField = sortField, sortOrder = sortOrder };
108             }
109             if (!string.IsNullOrEmpty(filter))
110             {
111                 this.queryItems = JsonHelper.Json2Object<List<QueryItem>>(filter);
112             }
113
114         }
115         //生成常量表达式
116         private ConstantExpression GetValueConstant(string value, Type type)
117         {
118             string typeName = type.Name.ToLower();
119             ConstantExpression rtn = null;
120             switch (typeName)
121             {
122                 case "int32":
123                     int intValue;
124                     if (!int.TryParse(value, out intValue))
125                     {
126                         rtn = Expression.Constant(false);
127                     }
128                     else
129                     {
130                         rtn = Expression.Constant(intValue);
131
132                     }
133                     break;
134                 case "string":
135
136                     rtn = Expression.Constant(value);
137                     break;
138                 case "float":
139                     float fValue;
140                     if (!float.TryParse(value, out fValue))
141                     {
142                         rtn = Expression.Constant(false);
143                     }
144                     else
145                     {
146                         rtn = Expression.Constant(fValue);
147
148                     }
149                     break;
150                 case "single":
151                     Single sgValue;
152                     if (!Single.TryParse(value, out sgValue))
153                     {
154                         rtn = Expression.Constant(false);
155                     }
156                     else
157                     {
158                         rtn = Expression.Constant(sgValue);
159
160                     }
161                     break;
162                 case "decimal":
163                     decimal dcValue;
164                     if (!decimal.TryParse(value, out dcValue))
165                     {
166                         rtn = Expression.Constant(false);
167                     }
168                     else
169                     {
170                         rtn = Expression.Constant(dcValue);
171
172                     }
173                     break;
174                 case "double":
175                     double dbValue;
176                     if (!double.TryParse(value, out dbValue))
177                     {
178                         rtn = Expression.Constant(false);
179                     }
180                     else
181                     {
182                         rtn = Expression.Constant(dbValue);
183
184                     }
185                     break;
186                 case "datetime":
187                     DateTime dateValue;
188                     if (!DateTime.TryParse(value, out dateValue))
189                     {
190                         rtn = Expression.Constant(false);
191                     }
192                     else
193                     {
194                         rtn = Expression.Constant(dateValue);
195
196                     }
197                     break;
198
199                 default:
200                     rtn = Expression.Constant(false);
201                     break;
202
203
204
205
206             }
207             return rtn;
208
209         }
210
211
212         //生成列表常量表达式  实现 In (‘a‘,‘b‘)
213         private ConstantExpression GetValueListConstant(string value, Type type)
214         {
215             string typeName = type.GenericTypeArguments.Length == 0 ? type.Name : type.GenericTypeArguments[0].Name;
216             ConstantExpression rtn = null;
217             switch (typeName.ToLower())
218             {
219                 case "int32":
220                     int intValue;
221                     string[] arrInt = value.Split(‘,‘);
222                     List<int> dlInt = new List<int>();
223                     foreach (string a in arrInt)
224                     {
225                         if (int.TryParse(a, out intValue))
226                         {
227                             dlInt.Add(intValue);
228                         }
229
230                     }
231                     if (dlInt.Count == 0)
232                     {
233                         rtn = Expression.Constant(false);
234
235                     }
236                     else
237                     {
238                         rtn = Expression.Constant(dlInt);
239                     }
240
241                     break;
242                 case "string":
243                     List<string> dlStr = value.Split(‘,‘).ToList();
244                     if (dlStr.Count == 0)
245                     {
246                         rtn = Expression.Constant(false);
247
248                     }
249                     else
250                     {
251                         rtn = Expression.Constant(dlStr);
252                     }
253                     break;
254
255
256                 default:
257                     rtn = Expression.Constant(false);
258                     break;
259
260
261
262
263             }
264             return rtn;
265
266         }
267
268
269         /// <summary>
270         /// 根据前台查询字段自动生成Lambad(支持=,like,between,in 查询)
271         /// </summary>
272         /// <returns></returns>
273         public Expression<Func<TEntity, bool>> BulidWhere()
274         {
275             Type type = typeof(TEntity);
276             string key = "";
277             string value = "";
278             string match = "";
279             string innerkey = "";
280             ParameterExpression instance = Expression.Parameter(type);
281             BinaryExpression result = Expression.Equal(Expression.Constant(true), Expression.Constant(true));
282             if (queryItems == null) return Expression.Lambda<Func<TEntity, bool>>(result, instance);
283             foreach (var item in queryItems)
284             {
285                 key = item.key;
286
287                 value = item.value;//.ToLower();
288                 if (string.IsNullOrEmpty(value)) continue;
289                 match = item.match.ToLower();
290                 innerkey = !string.IsNullOrEmpty(item.innerkey) ? item.innerkey : key;
291                 PropertyInfo propertyInfo = type.GetProperty(innerkey);
292                 var proFullType = propertyInfo.PropertyType;
293                 Type propertyType = proFullType.GenericTypeArguments.Length == 0 ? proFullType : proFullType.GenericTypeArguments[0];
294                 var valueExpression = match == "in" ? this.GetValueListConstant(value, propertyType) : this.GetValueConstant(value, propertyType);
295                 MemberExpression propertyExpression = Expression.Property(instance, propertyInfo);
296                 if (proFullType.Name.Contains("Nullable"))
297                 {
298                     propertyExpression = Expression.Property(propertyExpression, "Value");
299                 }
300                 var falseExpression = (Expression)Expression.Constant(false);
301                 if (valueExpression.Value.ToString() == "False")
302                 {
303
304                     result = Expression.And(result, falseExpression);
305                     continue;
306                 }
307                 switch (match)
308                 {
309                     case "=":
310                         result = Expression.And(result, Expression.Equal(propertyExpression, valueExpression));
311                         break;
312                     case "like":
313                         if (propertyType == typeof(string))
314                         {
315                             var like = Expression.Call(propertyExpression, typeof(string).GetMethod("Contains"), valueExpression);
316                             result = Expression.And(result, like);
317                         }
318                         else
319                         {
320                             result = Expression.And(result, falseExpression);
321
322                         }
323                         break;
324                     case "in":
325                         if (propertyType == typeof(string) || propertyType == typeof(Int32))
326                         {
327                             var inExp = Expression.Call(valueExpression, valueExpression.Type.GetMethod("Contains", new Type[] { propertyType }), propertyExpression);
328                             result = Expression.And(result, inExp);
329                         }
330                         else
331                         {
332                             result = Expression.And(result, falseExpression);
333
334                         }
335
336                         break;
337                     case "from":
338
339                         if (propertyType.IsValueType)
340                         {
341
342                             var from = Expression.GreaterThanOrEqual(propertyExpression, valueExpression);
343                             result = Expression.And(result, from);
344                         }
345                         else
346                         {
347                             result = Expression.And(result, falseExpression);
348
349                         }
350                         break;
351                     case "to":
352                         if (propertyType.IsValueType)
353                         {
354
355                             var from = Expression.LessThanOrEqual(propertyExpression, valueExpression);
356                             result = Expression.And(result, from);
357                         }
358                         else
359                         {
360                             result = Expression.And(result, falseExpression);
361
362                         }
363                         break;
364                 }
365             }
366             var lambda = Expression.Lambda<Func<TEntity, bool>>(result, instance);
367             return lambda;
368
369         }
370     }
371 }

这一套自动查询支持对应sql的 In,=,Like ,Between 查询,原理上也支持Not Like, Not In但是一般给用户的查询不会用到这些查询。

扩展EF框架的 DBSet:

 1 namespace App.PageBase.Query
 2 {
 3     // 摘要:
 4     //     提供一组用于查询实现 System.Linq.IQueryable<T> 的数据结构的 static(在 Visual Basic 中为 Shared)方法。
 5     public static class DbSet
 6     {
 7         /// <summary>
 8         /// 按QueryBulider自动生成 过滤,排序,分页
 9         /// </summary>
10         /// <typeparam name="T"></typeparam>
11         /// <param name="qb"></param>
12         /// <param name="query"></param>
13         /// <returns></returns>
14         public static IQueryable<T> Query<T>(this DbSet<T> qb, QueryBulider<T> query) where T : class,new()
15         {
16
17             var IQ = qb.Where(query.BulidWhere());
18             if (query.sort == null && query.pager != null)
19             {
20                 throw new Exception("列表分页时必须指定排序字段");
21             }
22
23             Type type = typeof(T);
24             var callWhere = IQ.Expression;
25             if (query.sort != null)
26             {
27                 var sortFieldProperty = type.GetProperty(query.sort.sortField);
28                 var instance =Expression.Parameter(type);
29                 var sortFieldExpression = Expression.Property(instance, sortFieldProperty);
30                 string OrderName = query.sort.sortOrder;
31                 if (OrderName.ToLower() == "desc")
32                 {
33                     OrderName = "OrderByDescending";
34                 }
35                 else
36                 {
37                     OrderName = "OrderBy";
38                 }
39
40                 Expression.Lambda(sortFieldExpression, instance);
41                 callWhere = Expression.Call(typeof(Queryable), OrderName, new Type[] { type, sortFieldProperty.PropertyType }, callWhere, Expression.Lambda(sortFieldExpression, instance));
42             }
43             if (query.pager != null)
44             {
45                 IQ = IQ.Provider.CreateQuery<T>(callWhere).Skip(query.pager.pageIndex * query.pager.pageSize).Take(query.pager.pageSize);
46             }
47
48             return IQ;
49
50         }
51
52
53     }

后台页面调用:

var  queryBulider = new QueryBulider<UserInfo>(Request.Form);

var dl = db.Set<UserInfo>().Query(queryBulider);

当然前台js组件不同,前台的封装就不一样。MiniUi我是这样弄的。

///组合查询条件

function GetQueryFormData(formId) {
var data = [];
if (!formId) formId = "queryForm";
var form = new mini.Form("#" + formId);
var fields = form.getFields();
var arr = [];
for (var i = 0; i < fields.length; i++) {
var item = {};
item["key"] = fields[i].id;
item["value"] = fields[i].value;
item["match"] = fields[i].match;
item["innerkey"] = fields[i].innerkey;
arr.push(item);
}

return arr;
}

///查询事件

function search() {
var grid = mini.get("datagrid1");
var query = GetQueryFormData();
var json = mini.encode(query);
grid.load({ filter: json });
}

				
时间: 2024-10-30 12:25:42

自动生成 Lambda查询和排序,从些查询列表so easy的相关文章

模糊查询和排序后合并查询结果集

今天需要做一个查询,当天时间按时间降序排列排在最前面,然后是其他的按时间降序排列排在当天的时间后面. select * from ( select * from Table  where time like '2015-11-16%' order by time desc ) a union all select * from (select * from Table  where id not in ( select Table.id from Table  where time like '

【Hibernate】Hibernate的聚类查询、分组查询、排序与时间之差

在Hibernate中的HQL语句其实能够基本能够实现SQL语句所做的事情,正如jQuery至于javascript一样.虽然HQL语句是对类的查询,但是HQL在实行聚类查询.分组查询.排序与时间之差等查询,也无须把查询结果查询出来,再通过对List的处理才得到结果. 比如有一张如下的Testtable表: 要像<[Mysql]求出离最近相差X天的项,sql语句关于日期的比对>(点击打开链接)一样,查询date字段离现在具有30年的项有多少,SQL语句则这样写: select count(*)

《卸甲笔记》-限定查询与排序显示

限定查询与排序显示 限定查询指的是在数据查询时设置一系列的过滤条件,只有满足指定的条件后才可以进行显示 在SQL标准中限定查询的语法如下: select [distinct] *|列名称 [as] [列别名],列名称 [as] [列别名], … from 表名称 [表别名] [where 条件(s)] 1查看emp表中的数据量 Oracle SQL> select count(*) from emp; COUNT(*) ---------- 14 PPAS scott=# select coun

自动生成SQL查询、删除、更新、插入语句

自动生成sql语句 select 'update  ' || t.table_name || ' a  set ' ||       (select wm_concat('a.' || a.column_name || '=' || Chr(39) || '{' ||                         Abs(Rownum - 1) || '}' || chr(39) || '   --' ||                         a.Comments || Chr(1

查询自动生成Guid列

--newid()可以在查询的时候自动生成Guid列 select top 10 *,newid() as Random from ywle where ywlename='001' ordey by Random --创建对应的列 用 uniqueidentifier 类型 IF NOT EXISTS ( SELECT * FROM dbo.SysObjects WHERE ID = object_id(N'[RMA_ExchangeOrderAddTempInfo]') AND OBJECT

mybatis多表查询,自动生成id

主要是在配置文件中,配置好所要包含的字段. 类关系:account----role,1对1 account包含role类 java类: public class Account{ private Integer accountId; private String username; private String password; private Role role; } public class Role { private Integer id; private Integer leave;

SpringBoot与Mybatis整合(包含generate自动生成代码工具,数据库表一对一,一对多,关联关系中间表的查询)

链接:https://blog.csdn.net/YonJarLuo/article/details/81187239 自动生成工具只是生成很单纯的表,复杂的一对多,多对多要自己在xml中写! 添加mybatis的generator插件: 链接:https://blog.csdn.net/readyyy/article/details/85935365 原文地址:https://www.cnblogs.com/wskb/p/11582711.html

Asp.net自动生成三层代码视频教程

下载地址,百度网盘: http://pan.baidu.com/s/1jG4GwDo 目前已经录制4集. 第一集:自动生成三层框架代码,自动生成的代码是Model层,DAL层,BLL层等. 第二集:使用delegate排序,使用Lambda排序,使用Predicate使用条件,选择List集合. 第三集:使用LINQ进行跨表查询并显示. 第四集:将选出的表数据导出到Excel当中.

[Oracle系列整理01]PL/SQL 基本查询与排序

本课重点:    1.写SELECT语句进行数据库查询    2.进行数学运算    3.处理空值    4.使用别名ALIASES    5.连接列    6.在SQL PLUS中编辑缓冲,修改SQL SCRIPTS    7.ORDER BY进行排序输出.    8.使用WHERE 字段. 一.写SQL 命令:      不区分大小写.      SQL 语句用数字分行,在SQL PLUS中被称为缓冲区.      最后以:或 / 结束语句.      也可以用RUN来执行语句 二.例1: