自动生成 Lambda查询和排序,从些查询列表so easy
如下图查询页面,跟据不同条件动态生成lambda的Where条件和OrderBy,如果要增加或调整查询,只用改前台HTML即可,不用改后台代码
前台代码:
<div style="padding-bottom: 5px;" id="queryForm"> <span>员工姓名:</span><input type="text" emptytext="ddd" data-options="{match:'in'}" class="mini-textbox" id="Age" />
<span>部门:</span><input type="text" class="mini-textbox" data-options="{match:'like'}" id="Sex" /> 生日从 <input id="beg" format="yyyy-MM-dd" showokbutton="false" showclearbutton="true" data-options="{match:'from',innerkey:'Birthday'}" class="mini-datepicker" />
至 <input id="end" format="yyyy-MM-dd" showokbutton="false" showclearbutton="true" data-options="{match:'to',innerkey:'Birthday'}" class="mini-datepicker" /> <span>年龄从:</span><input type="text" emptytext="ddd" data-options="{match:'from',innerkey:'Age'}" class="mini-textbox" id="bb" />
<span>至:</span><input type="text" class="mini-textbox" data-options="{match:'to',innerkey:'Age'}" id="bd" /> <a class="mini-button" iconcls="icon-search" onclick="search()">查找</a> </div> <div id="datagrid1" ondrawcell="Link" onupdate="load" class="mini-datagrid" style="width: 100%; height: 100%;" allowresize="true"
idfield="Id" sortfield="Age" showpager="false" pagesize="-1" sizelist="[-1]" sortorder="asc" multiselect="true">
<div property="columns">
<!--<div type="indexcolumn"></div> -->
<div type="checkcolumn"></div>
<div field="UserName" data-options="{Func:'test'}" width="120" headeralign="center" allowsort="true">姓名</div>
<div field="Sex" renderer="SexShow" width="120" headeralign="center" allowsort="true">性别</div> <div field="LoginName" width="120">登录名</div>
<div field="Password" width="120">密码</div>
<div field="Birthday" width="100">生日</div>
<div field="Age" width="100" allowsort="true">年龄</div>
<div field="Remark" align="right" width="100">备注</div> <div field="Married" renderer="MarriedShow" width="100">婚否</div> </div>
</div>
查询控件上的 data-options="{match:'from',innerkey:'Birthday'}" 后多个查询条件会组合成一个json数组,传到后台,反序列化成List<QueryItem>,
排序条件Jquery 的Grid控件也会传到后台的,反序列化成SortItem,分页信息 反序列化成 Pager,详见后台代码。
上后台代码:比较复杂
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using App.Core;
using System.Reflection;
using System.Linq.Expressions;
using System.Data.Entity;
using System.Collections.Specialized;
namespace App.PageBase.Query
{
//查询条件模型
public class QueryItem
{
public string match { get; set; }
public string value { get; set; }
public string key { get; set; }
public string innerkey { get; set; } }
//排序模型
public class SortItem
{ public string sortField { get; set; }
public string sortOrder { get; set; }
}
//列表分页模型
public class Pager
{
public int pageSize
{
get;
set;
}
public int pageIndex
{
get;
set;
}
public int totalCount
{
get;
set;
} } //生成查询条件类
public class QueryBulider<TEntity> where TEntity : class,new()
{
private Pager _pager;// = new Pager();
private SortItem _sort;// = new SortItem();
private List<QueryItem> _queryItems;//= new List<QueryItem>();
public Pager pager
{
get { return _pager; }
set { _pager = value; }
}
public SortItem sort
{
get { return _sort; }
set { _sort = value; }
}
public List<QueryItem> queryItems
{
get { return _queryItems; }
set { _queryItems = value; }
}
/// <summary>
/// 根据 分页模型,排序模型,查询条件模型列表构造 自动查询生成器
/// </summary>
/// <param name="pager"></param>
/// <param name="sort"></param>
/// <param name="queryItems"></param>
public QueryBulider(Pager pager, SortItem sort, List<QueryItem> queryItems)
{
this.pager = pager;
this.sort = sort;
this.queryItems = queryItems; }
public QueryBulider()
{ } /// <summary>
/// 根据HTTP实例化
/// </summary>
/// <param name="requstForm"></param>
public QueryBulider(NameValueCollection requstForm)
{
string filter = requstForm["filter"];
string pageIndex = requstForm["pageIndex"];
string pageSize = requstForm["pageSize"];
string sortField = requstForm["sortField"];
string sortOrder = requstForm["sortOrder"]; if (!string.IsNullOrEmpty(pageSize) && !string.IsNullOrEmpty(pageIndex)&&pageSize!="-1")
{
this.pager = new Pager { pageIndex = int.Parse( pageIndex), pageSize = int.Parse( pageSize) };
}
if (!string.IsNullOrEmpty(sortField))
{
this.sort = new SortItem { sortField = sortField, sortOrder = sortOrder };
}
if (!string.IsNullOrEmpty(filter))
{
this.queryItems = JsonHelper.Json2Object<List<QueryItem>>(filter);
} }
//生成常量表达式
private ConstantExpression GetValueConstant(string value, Type type)
{
string typeName = type.Name.ToLower();
ConstantExpression rtn = null;
switch (typeName)
{
case "int32":
int intValue;
if (!int.TryParse(value, out intValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(intValue); }
break;
case "string": rtn = Expression.Constant(value);
break;
case "float":
float fValue;
if (!float.TryParse(value, out fValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(fValue); }
break;
case "single":
Single sgValue;
if (!Single.TryParse(value, out sgValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(sgValue); }
break;
case "decimal":
decimal dcValue;
if (!decimal.TryParse(value, out dcValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(dcValue); }
break;
case "double":
double dbValue;
if (!double.TryParse(value, out dbValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(dbValue); }
break;
case "datetime":
DateTime dateValue;
if (!DateTime.TryParse(value, out dateValue))
{
rtn = Expression.Constant(false);
}
else
{
rtn = Expression.Constant(dateValue); }
break; default:
rtn = Expression.Constant(false);
break; }
return rtn; } //生成列表常量表达式 实现 In ('a','b')
private ConstantExpression GetValueListConstant(string value, Type type)
{
string typeName = type.GenericTypeArguments.Length == ? type.Name : type.GenericTypeArguments[].Name;
ConstantExpression rtn = null;
switch (typeName.ToLower())
{
case "int32":
int intValue;
string[] arrInt = value.Split(',');
List<int> dlInt = new List<int>();
foreach (string a in arrInt)
{
if (int.TryParse(a, out intValue))
{
dlInt.Add(intValue);
} }
if (dlInt.Count == )
{
rtn = Expression.Constant(false); }
else
{
rtn = Expression.Constant(dlInt);
} break;
case "string":
List<string> dlStr = value.Split(',').ToList();
if (dlStr.Count == )
{
rtn = Expression.Constant(false); }
else
{
rtn = Expression.Constant(dlStr);
}
break; default:
rtn = Expression.Constant(false);
break; }
return rtn; } /// <summary>
/// 根据前台查询字段自动生成Lambad(支持=,like,between,in 查询)
/// </summary>
/// <returns></returns>
public Expression<Func<TEntity, bool>> BulidWhere()
{
Type type = typeof(TEntity);
string key = "";
string value = "";
string match = "";
string innerkey = "";
ParameterExpression instance = Expression.Parameter(type);
BinaryExpression result = Expression.Equal(Expression.Constant(true), Expression.Constant(true));
if (queryItems == null) return Expression.Lambda<Func<TEntity, bool>>(result, instance);
foreach (var item in queryItems)
{
key = item.key; value = item.value;//.ToLower();
if (string.IsNullOrEmpty(value)) continue;
match = item.match.ToLower();
innerkey = !string.IsNullOrEmpty(item.innerkey) ? item.innerkey : key;
PropertyInfo propertyInfo = type.GetProperty(innerkey);
var proFullType = propertyInfo.PropertyType;
Type propertyType = proFullType.GenericTypeArguments.Length == ? proFullType : proFullType.GenericTypeArguments[];
var valueExpression = match == "in" ? this.GetValueListConstant(value, propertyType) : this.GetValueConstant(value, propertyType);
MemberExpression propertyExpression = Expression.Property(instance, propertyInfo);
if (proFullType.Name.Contains("Nullable"))
{
propertyExpression = Expression.Property(propertyExpression, "Value");
}
var falseExpression = (Expression)Expression.Constant(false);
if (valueExpression.Value.ToString() == "False")
{ result = Expression.And(result, falseExpression);
continue;
}
switch (match)
{
case "=":
result = Expression.And(result, Expression.Equal(propertyExpression, valueExpression));
break;
case "like":
if (propertyType == typeof(string))
{
var like = Expression.Call(propertyExpression, typeof(string).GetMethod("Contains"), valueExpression);
result = Expression.And(result, like);
}
else
{
result = Expression.And(result, falseExpression); }
break;
case "in":
if (propertyType == typeof(string) || propertyType == typeof(Int32))
{
var inExp = Expression.Call(valueExpression, valueExpression.Type.GetMethod("Contains", new Type[] { propertyType }), propertyExpression);
result = Expression.And(result, inExp);
}
else
{
result = Expression.And(result, falseExpression); } break;
case "from": if (propertyType.IsValueType)
{ var from = Expression.GreaterThanOrEqual(propertyExpression, valueExpression);
result = Expression.And(result, from);
}
else
{
result = Expression.And(result, falseExpression); }
break;
case "to":
if (propertyType.IsValueType)
{ var from = Expression.LessThanOrEqual(propertyExpression, valueExpression);
result = Expression.And(result, from);
}
else
{
result = Expression.And(result, falseExpression); }
break;
}
}
var lambda = Expression.Lambda<Func<TEntity, bool>>(result, instance);
return lambda; }
}
}
这一套自动查询支持对应sql的 In,=,Like ,Between 查询,原理上也支持Not Like, Not In但是一般给用户的查询不会用到这些查询。
扩展EF框架的 DBSet:
namespace App.PageBase.Query
{
// 摘要:
// 提供一组用于查询实现 System.Linq.IQueryable<T> 的数据结构的 static(在 Visual Basic 中为 Shared)方法。
public static class DbSet
{
/// <summary>
/// 按QueryBulider自动生成 过滤,排序,分页
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="qb"></param>
/// <param name="query"></param>
/// <returns></returns>
public static IQueryable<T> Query<T>(this DbSet<T> qb, QueryBulider<T> query) where T : class,new()
{ var IQ = qb.Where(query.BulidWhere());
if (query.sort == null && query.pager != null)
{
throw new Exception("列表分页时必须指定排序字段");
} Type type = typeof(T);
var callWhere = IQ.Expression;
if (query.sort != null)
{
var sortFieldProperty = type.GetProperty(query.sort.sortField);
var instance =Expression.Parameter(type);
var sortFieldExpression = Expression.Property(instance, sortFieldProperty);
string OrderName = query.sort.sortOrder;
if (OrderName.ToLower() == "desc")
{
OrderName = "OrderByDescending";
}
else
{
OrderName = "OrderBy";
} Expression.Lambda(sortFieldExpression, instance);
callWhere = Expression.Call(typeof(Queryable), OrderName, new Type[] { type, sortFieldProperty.PropertyType }, callWhere, Expression.Lambda(sortFieldExpression, instance));
}
if (query.pager != null)
{
IQ = IQ.Provider.CreateQuery<T>(callWhere).Skip(query.pager.pageIndex * query.pager.pageSize).Take(query.pager.pageSize);
} return IQ; } }
后台页面调用:
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 });
}
自动生成 Lambda查询和排序,从些查询列表so easy的更多相关文章
- mysql 更新与查询(排序 分组 链接查询)
UPDATE更新 #每一次数据的更新都需要update UPDATE 命令修改 MySQL 数据表数据的通用 SQL 语法: UPDATE table_name SET field1=new-valu ...
- Mybatis使用generator自动生成的Example类使用OR条件查询
参考:https://blog.csdn.net/qq_36614559/article/details/80354511 public List<AssetsDevicetypeRefacto ...
- springboot学习随笔(四):Springboot整合mybatis(含generator自动生成代码)
这章我们将通过springboot整合mybatis来操作数据库 以下内容分为两部分,一部分主要介绍generator自动生成代码,生成model.dao层接口.dao接口对应的sql配置文件 第一部 ...
- MySQL数据库6 -查询基础,简单查询,条件查询,对查询结果排序
一.SELECT语句 SELECT COL1,COL2,....COLn FROM TABLE1,TABLE2,....TABLEn [WHERE CONDITIONS] -- 查询条件 [GROUP ...
- MySQL数据库—查询基础,简单查询,条件查询,对查询结果排序
一.SELECT语句 SELECT COL1,COL2,....COLn FROM TABLE1,TABLE2,....TABLEn [WHERE CONDITIONS] -- 查询条件 [GROUP ...
- 9.1.2 asp.net core 自动生成组合查询
在做系统的时候,经常遇到前台录入一大堆的查询条件,然后点击查询提交后台,在Controller里面生成对应的查询SQL或者表达式,数据库执行再将结果返回客户端. 例如如下页面,输入三个条件,日志类型. ...
- drf07 过滤 排序 分页 异常处理 自动生成接口文档
4. 过滤Filtering 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持. pip install django-filter 在配置文件sett ...
- day74:drf:drf其他功能:认证/权限/限流/过滤/排序/分页/异常处理&自动生成接口文档
目录 1.django-admin 2.认证:Authentication 3.权限:Permissions 4.限流:Throttling 5.过滤:Filtering 6.排序:OrderingF ...
- SQL参数化查询自动生成SqlParameter列表
string sql = @"INSERT INTO stu VALUES (@id,@name) "; 参数化查询是经常用到的,它可以有效防止SQL注入.但是需要手动去匹配参数@ ...
随机推荐
- JavaWeb学习笔记之JSP(一)
1. JSP: 1.1. 为什么需要 JSP ? 如果使用Servlet程序来输出只有局部内容需要动态改变的网页,但是其中的静态网页内容也需要程序员使用Java语言来进行输出,这就造成了大量代码的冗余 ...
- 单点登录CAS使用记(三):实现自定义验证用户登录
问题: CAS自带的用户验证逻辑太过简单,如何像正常网站一样,通过验证DB中的用户数据,来验证用户以及密码的合法性呢? 方案1:CAS默认的JDBC扩展方案: CAS自带了两种简单的通过JDBC方式验 ...
- PHP高效的敏感词过滤方法
<?php // 测试文件demo.php $badword = array( '张三','张三丰','张三丰田' ); // array_combine() 函数通过合并两个数组来创建一个新数 ...
- mysql innerjoin left join right join 解析
毕业半年多时间,一直都没有学习好join 之前一直是先从一个表里面取出数据然后,然后再从另外一个表里面取出数据,然后再写一个函数循环格式化数据. 还是先写一下学到的东西吧! 转载自w3school ...
- php 编码规范(1)
1. 包含尽量不要使用短标签例如 <? #coding ?> 2. 忽略结束标签,防止其他字符或者空格影响到代码 <?php$foo = 'foo'; 如果不开启压缩或者缓存输出时候 ...
- MVC 中集成 AngularJS1
在 ASP.NET MVC 中集成 AngularJS(1) 介绍 当涉及到计算机软件的开发时,我想运用所有的最新技术.例如,前端使用最新的 JavaScript 技术,服务器端使用最新的基于 R ...
- JS操作css的float属性的特殊写法
使用js操作css属性的写法是有一定的规律的: 1.对于没有中划线的css属性一般直接使用style.属性名即可. 如:obj.style.margin,obj.style.width,obj.sty ...
- 转:单片机C语言中的data,idata,xdata,pdata,code
从数据存储类型来说,8051系列有片内.片外程序存储器,片内.片外数据存储器,片内程序存储器还分直接寻址区和间接寻址类型,分别对应code.data.xdata.idata以及根据51系列特点而设定的 ...
- ural 1613 For Fans of Statistics
#include <cstdio> #include <cstring> #include <map> #include <vector> #inclu ...
- [转]The culture name list in C#
Culture Names [C#] This example shows how to get all culture names in the .NET Framework. Use static ...