动态创建Lambda表达式实现高级查询
需求简介
最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表。其
中有一个功能是一个高级查询的需求,在查询条件方面大概有7、8个查询条件。需求就是如果一个条件都不输入就默
认查询全部的数据,那个条件不为空的时候就在查询条件上面添加对响应字段的限制,也就是说我们在写查询条件的
时候不能写死,因为我们不知道我们到底有几个条件?到底有几个条件。所以需要我们动态的创建Lambd表达式。看
了看他们相似的功能,在实现的时候用的动态拼接SQL语句,那些SQL代码啊?看到都头疼,所以我直接放弃了,用咱
自己熟悉的知识来实现。和这个相似的功能自己在之前的《图书馆项目》中实现过,请点击我。
具体实现—小Demo
首先需要引入命名空间
using System.Linq.Expressions.Expression;
- //创建一个数组用来当做例子
- var ints = new int []{ 1, 2 , 3 , 4 , 5 , 6 };
- // 要创建形如 i => i < 5
- //创建参数 i
- var parameter = Expression.Parameter(typeof(int),”i”);
- //创建常数 5
- var constant = Expression.Constant(5);
- //创建 i > 5
- var bin = Expression.GreaterThan(parameter,constant);
- //获取Lambda表达式
- var lambda=Expression.Lambda<Func<Int32,Boolean>>(bin,parameter);
- //取得查询结果
- var query = ints.Where(lambda.Compile());
通过上面一个小Demo我们可以简单的看到动态创建Lambda表达式的雏形,下面在介绍一个比较复杂的例子。
- BinaryExpression condition = null;
- //要构造的表达式i==1||i==2||i==3.....
- for (int i = 0; i < ints.Length; i++)
- {
- ConstantExpression ce = Expression.Constant(i);
- if (condition == null)
- {
- condition = Expression.Equal(parameter, ce);
- }
- else
- {
- var right = Expression.Equal(parameter, ce);
- condition = Expression.Or(condition, right);
- }
- }
- Expression<Func<Int32, Boolean>> lambda = Expression.Lambda<Func<Int32, Boolean>>(condition, parameter);
实体类的实现
上面都是比较简单的小例子,但是在我们项目中都是来对实体进行条件查询的,所以呢小编在下面会给大家介
绍一下如何对实体类进行构造。
- //p => p.Name == "1" && p.Address == "2"
- ParameterExpression parameter1 = Expression.Parameter(typeof(Person), "p");
- MemberExpression member1 = Expression.PropertyOrField(parameter1, "Name");
- MemberExpression member2 = Expression.PropertyOrField(parameter1, "Address"),
- ConstantExpression constant1 = Expression.Constant("郑浩");
- ConstantExpression constant2 = Expression.Constant("河北");
- var query1 = Expression.Equal(member1, constant1);//Equal等于;GreaterThanOrEqual大于;LessThanOrEqual小于
- var query2 = Expression.Equal(member2, constant2);
- var query = Expression.And(query1, query2);//and 与;or或
- var lambda1 = Expression.Lambda<Func<Person, Boolean>>(query, parameter1);
- var list = MethodExtend.GetUser(lambda1.Compile());
代码介绍:
1)创建表达式的开始部分:p=>
2、3)创建我们要查询的字段:p.Name和p.Address
4、5)给给变量赋值,这些值和变量可以任意匹配
6、7)匹配查询条件和对应的值:p.Name=="郑浩";p.Address=="河北"
8、9)连接查询条件;p.Name=="郑浩"&&p.Address=="河北"
10)创建最后的查询条件:p=>p.Name=="郑浩"&&p.Address=="河北"
11)最后执行查询条件
项目实战
我首先创建了一个接口,因为这个功能不是我自己使用,还有别的模块也需要这个功能;
- namespace Seagull2.Investment.WebApi
- {
- /// <summary>
- /// 可实现表达式接口
- /// </summary>
- public interface IExpressionable<T> where T : class
- {
- /// <summary>
- /// 创建表达式
- /// </summary>
- /// <returns></returns>
- Expression<Func<T, bool>> CreateExpression();
- }
- }
我将创建Landa表达式的部分放在module中,这个module是和界面对应,接收界面传递参数,代码如下:
- public class RealEstateProjectCondition : IExpressionable<View_RealEstateProject>
- {
- /// <summary>
- /// 项目所在省份
- /// </summary>
- public string ProjectOfProvince { get; set; }
- /// <summary>
- /// 项目所在城市
- /// </summary>
- public string ProjectOfCity { get; set; }
- /// <summary>
- /// 项目业态名称
- /// </summary>
- public string ProjectFormatName { get; set; }
- /// <summary>
- /// 所属业务团队
- /// </summary>
- public string BusiGroup { get; set; }
- /// <summary>
- /// 项目所处阶段
- /// </summary>
- public string PrjStageCode { get; set; }
- /// <summary>
- /// 申请起始日期
- /// </summary>
- public DateTimeOffset? ApplyStartDate { get; set; }
- /// <summary>
- /// 申请起始日期
- /// </summary>
- public DateTimeOffset? ApplyEndDate { get; set; }
- /// <summary>
- /// 基金规模(亿元)上线
- /// </summary>
- public decimal? StartFundSize { get; set; }
- /// <summary>
- /// 基金规模(亿元)下线
- /// </summary>
- public decimal? EndFundSize { get; set; }
- /// <summary>
- /// 创建房地产投资查询条件表达式
- /// </summary>
- /// <returns></returns>
- public Expression<Func<View_RealEstateProject, bool>> CreateExpression()
- {
- ParameterExpression parameter = Expression.Parameter(typeof(View_RealEstateProject), "p");
- //项目类型编码
- ConstantExpression constantPrjTypeCode = Expression.Constant("A0BE01A2-1BE3-4AAE-8DE3-B84BB6B2A58A");
- MemberExpression memberPrjTypeCode = Expression.PropertyOrField(parameter, "PrjTypeCode");
- var query = Expression.Equal(memberPrjTypeCode, constantPrjTypeCode);
- //项目所在省份
- if (!string.IsNullOrEmpty(this.ProjectOfProvince))
- {
- ConstantExpression constantProjectOfProvince = Expression.Constant(this.ProjectOfProvince);
- MemberExpression memberProjectOfCity = Expression.PropertyOrField(parameter, "ProjectOfProvince");
- query = Expression.And(query, Expression.Equal(memberProjectOfCity, constantProjectOfProvince));
- }
- //项目所在城市
- if (!string.IsNullOrEmpty(this.ProjectOfCity))
- {
- ConstantExpression constantProjectOfCity = Expression.Constant(this.ProjectOfCity);
- MemberExpression memberProjectOfCity = Expression.PropertyOrField(parameter, "ProjectOfCity");
- query = Expression.And(query, Expression.Equal(memberProjectOfCity, constantProjectOfCity));
- }
- //项目业态名称
- if (!string.IsNullOrEmpty(this.ProjectFormatName))
- {
- ConstantExpression constantProjectFormatName = Expression.Constant(this.ProjectFormatName);
- MemberExpression memberProjectFormatName = Expression.PropertyOrField(parameter, "ProjectFormatName");
- query = Expression.And(query, Expression.Equal(memberProjectFormatName, constantProjectFormatName));
- }
- //所属业务团队
- if (!string.IsNullOrEmpty(this.BusiGroup))
- {
- ConstantExpression constantBusiGroup = Expression.Constant(this.BusiGroup);
- MemberExpression memberBusiGroup = Expression.PropertyOrField(parameter, "BusiGroup");
- query = Expression.And(query, Expression.Equal(memberBusiGroup, constantBusiGroup));
- }
- //项目所处阶段
- if (!string.IsNullOrEmpty(this.PrjStageCode))
- {
- ConstantExpression constantPrjStageCode = Expression.Constant(this.PrjStageCode);
- MemberExpression memberPrjStageCode = Expression.PropertyOrField(parameter, "PrjStageCode");
- query = Expression.And(query, Expression.Equal(memberPrjStageCode, constantPrjStageCode));
- }
- //申请开始时间
- if (this.ApplyStartDate.HasValue)
- {
- ConstantExpression constantApplyStartDate = Expression.Constant(this.ApplyStartDate.Value);
- MemberExpression memberApplyStartDate = Expression.PropertyOrField(parameter, "ApplyDate");
- query = Expression.And(query, Expression.GreaterThanOrEqual(memberApplyStartDate, constantApplyStartDate));
- }
- //申请结束时间
- if (this.ApplyEndDate.HasValue)
- {
- ConstantExpression constantApplyEndDate = Expression.Constant(this.ApplyEndDate.Value);
- MemberExpression memberApplyEndDate = Expression.PropertyOrField(parameter, "ApplyDate");
- query = Expression.And(query, Expression.LessThanOrEqual(memberApplyEndDate, constantApplyEndDate));
- }
- //投资规模(亿元)上线
- if (this.StartFundSize.HasValue)
- {
- ConstantExpression constantStartFundSize = Expression.Constant(this.StartFundSize.Value);
- MemberExpression memberStartFundSize = Expression.PropertyOrField(parameter, "FundSize");
- query = Expression.And(query, Expression.GreaterThanOrEqual(memberStartFundSize, constantStartFundSize));
- }
- //投资规模(亿元)下线
- if (this.EndFundSize.HasValue)
- {
- ConstantExpression constantEndFundSize = Expression.Constant(this.EndFundSize.Value);
- MemberExpression memberEndFundSize = Expression.PropertyOrField(parameter, "FundSize");
- query = Expression.And(query, Expression.LessThanOrEqual(memberEndFundSize, constantEndFundSize));
- }
- //版本结束时间
- ConstantExpression constantVesionEndTime = Expression.Constant(null);
- MemberExpression memberVesionEndTime = Expression.PropertyOrField(parameter, "VersionEndTime");
- query = Expression.And(query, Expression.Equal(memberVesionEndTime, constantVesionEndTime));
- //有效性
- ConstantExpression constantValidStatus = Expression.Constant(true);
- MemberExpression memberValidStatus = Expression.PropertyOrField(parameter, "ValidStatus");
- query = Expression.And(query, Expression.Equal(memberValidStatus, constantValidStatus));
- return Expression.Lambda<Func<View_RealEstateProject, bool>>(query, parameter);
- }
- }
这样我们的controller和service都非常的简单明了,把查询条件作为实体的一部分。
service代码:
- public List<View_RealEstateProject> LoadView_RealEstateProject(RealEstateProjectCondition condition)
- {
- using (var db = new InvestmentDbContext())
- {
- return db.View_RealEstateProject.Where(condition.CreateExpression()).ToList();
- }
- }
controller代码:
- [HttpPost, HttpGet]
- public IHttpActionResult LoadQueryResult(RealEstateProjectCondition condition)
- {
- return Json(_realEstabDasbordService.LoadView_RealEstateProject(condition));
- }
小结
关于动态创建Lamda表达式就给大家介绍到这,通过动态创建表达式非常方便实现高级查询,和拼接sql来说这
还是非常简单的,并且出错的几率大大降低,所以我没有采用他们类似功能的实现,所以说我们在实现某些需求的时
候需要我们好好考虑在下手写代码,能参考的东西不一定是最合适的,还需要我们自己探索一些,希望给大家带来帮
助。
http://blog.csdn.net/hao134838/article/details/51404151
动态创建Lambda表达式实现高级查询的更多相关文章
- C#动态创建lambda表达式
/// <summary> /// 创建lambda表达式:p=>true /// </summary> /// <typeparam name="T&q ...
- 使用Expression动态创建lambda表达式
using System;using System.Linq.Expressions;using System.Reflection; namespace Helper{ public class L ...
- 动态创建 Lambda 表达式
首先我们看一个简单 Lambda 表达式的构成. i => i > 5 在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 ...
- 动态组合lambda 表达式
//记录实体集合—动态组合lambda 表达式 Expression<Func<AdEntity, bool>> thirdWhere = p => p.Observer ...
- easyui datagrid remoteSort的实现 Controllers编写动态的Lambda表达式 IQueryable OrderBy扩展
EF 结合easy-ui datagrid 实现页面端排序 EF动态编写排序Lambda表达式 1.前端页面 var mainListHeight = $(window).height() - 20; ...
- 【转】EntityFramework动态组合Lambda表达式作为数据筛选条件,代替拼接SQL语句
传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...
- C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询
1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...
- [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)
声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...
- 动态构建Lambda表达式实现EF动态查询
在使用Entity Framework做数据查询的时候,查询条件往往不是固定的,需要动态查询.可以通过动态构建Lamda表达式来实现动态查询. Lamda表达式 使用Lamda表达式可以很方便的按条件 ...
随机推荐
- 咏南下拉列表非数据敏感控件--TYNSearch
咏南下拉列表非数据敏感控件--TYNSearch 拥有下拉列表控件可以大大地加速软件系统的开发. 控件适用于DELPHI5及以上版本的安装和使用. 控件的使用方法: procedure Tflog.s ...
- python良好的编程习惯
良好的编程习惯 2.1 在程序中是用丰富的注释,注释有助于其他程序员理解程序,有助于程序调试(发现和排除程序中的错误),并列出有用的信息.以后修改或更新代码时,注释还有助于理解当初自己编写的程序 2. ...
- 关于container_of和list_for_each_entry 及其相关函数的分析
Linux代码看的比较多了,经常会遇到container_of和list_for_each_entry,特别是 list_for_each_entry比较多,因为Linux经常用到链表,虽然知道这些函 ...
- 【Hadoop】Hadoop 机架感知配置、原理
Hadoop机架感知 1.背景 Hadoop在设计时考虑到数据的安全与高效,数据文件默认在HDFS上存放三份,存储策略为本地一份, 同机架内其它某一节点上一份,不同机架的某一节点上一份. 这样如果本地 ...
- lua基础【三】唯一数据结构table表
--[[ 数据结构table对象(一种动态分配的对象) lua中的表操作.table类型实现了"关联数组的". "关联数组是一种具有特殊索引方式的数组" 能够通 ...
- 安装openstack 时 遇见的一些问题及解决方法!
感谢朋友支持本博客,欢迎共同探讨交流.因为能力和时间有限,错误之处在所难免.欢迎指正! 假设转载.请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...
- Swif语法基础 要点归纳(一)
常量和变量 用let声明常量 let m = 20 用var声明变量 var n = 0 类型推导机制 声明常量或变量时.能够不指定常量/变量类型,编译器会依据 ...
- How to Handle Exception
- UISearchBar 点击取消回到原来位置时会跳动的解决方法
今天改动项目里面測试给提的bug.有一个bug就是当点击UISearchBar的取消buttonUISearchBar回到原来位置时会发生偏差50像素左右的跳动,细致看看前面几个程序写的那个页面,也没 ...
- web前端性能优化汇总
一.概述 web前端性能优化主要点为:减少HTTP请求,减小请求文件大小.其他优化. 二.优化细节 1.减少HTTP请求 (1)使用缓存 (2)雪碧图 (3)合并文件 (4)将javascript和c ...