需求简介

最近这几天做的东西总算是回归咱的老本行了,给投资管理项目做一个台账的东西,就是类似我们的报表。其

中有一个功能是一个高级查询的需求,在查询条件方面大概有7、8个查询条件。需求就是如果一个条件都不输入就默

认查询全部的数据,那个条件不为空的时候就在查询条件上面添加对响应字段的限制,也就是说我们在写查询条件的

时候不能写死,因为我们不知道我们到底有几个条件?到底有几个条件。所以需要我们动态的创建Lambd表达式。看

了看他们相似的功能,在实现的时候用的动态拼接SQL语句,那些SQL代码啊?看到都头疼,所以我直接放弃了,用咱

自己熟悉的知识来实现。和这个相似的功能自己在之前的《图书馆项目》中实现过,请点击我

具体实现—小Demo

首先需要引入命名空间

using System.Linq.Expressions.Expression;

  1. //创建一个数组用来当做例子
  2. var ints = new int []{ 1, 2 , 3 , 4 , 5 , 6 };
  3. // 要创建形如 i => i < 5
  4. //创建参数 i
  5. var parameter  = Expression.Parameter(typeof(int),”i”);
  6. //创建常数 5
  7. var constant = Expression.Constant(5);
  8. //创建 i > 5
  9. var bin = Expression.GreaterThan(parameter,constant);
  10. //获取Lambda表达式
  11. var lambda=Expression.Lambda<Func<Int32,Boolean>>(bin,parameter);
  12. //取得查询结果
  13. var query = ints.Where(lambda.Compile());

通过上面一个小Demo我们可以简单的看到动态创建Lambda表达式的雏形,下面在介绍一个比较复杂的例子。

  1. BinaryExpression condition = null;
  2. //要构造的表达式i==1||i==2||i==3.....
  3. for (int i = 0; i < ints.Length; i++)
  4. {
  5. ConstantExpression ce = Expression.Constant(i);
  6. if (condition == null)
  7. {
  8. condition = Expression.Equal(parameter, ce);
  9. }
  10. else
  11. {
  12. var right = Expression.Equal(parameter, ce);
  13. condition = Expression.Or(condition, right);
  14. }
  15. }
  16. Expression<Func<Int32, Boolean>> lambda = Expression.Lambda<Func<Int32, Boolean>>(condition, parameter);

实体类的实现

上面都是比较简单的小例子,但是在我们项目中都是来对实体进行条件查询的,所以呢小编在下面会给大家介

绍一下如何对实体类进行构造。

  1. //p => p.Name == "1" && p.Address == "2"
  2. ParameterExpression parameter1 = Expression.Parameter(typeof(Person), "p");
  3. MemberExpression member1 = Expression.PropertyOrField(parameter1, "Name");
  4. MemberExpression member2 =  Expression.PropertyOrField(parameter1, "Address"),
  5. ConstantExpression constant1 = Expression.Constant("郑浩");
  6. ConstantExpression constant2 = Expression.Constant("河北");
  7. var query1 = Expression.Equal(member1, constant1);//Equal等于;GreaterThanOrEqual大于;LessThanOrEqual小于
  8. var query2 = Expression.Equal(member2, constant2);
  9. var query = Expression.And(query1, query2);//and 与;or或
  10. var lambda1 = Expression.Lambda<Func<Person, Boolean>>(query, parameter1);
  11. 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)最后执行查询条件

项目实战

 

我首先创建了一个接口,因为这个功能不是我自己使用,还有别的模块也需要这个功能;

  1. namespace Seagull2.Investment.WebApi
  2. {
  3. /// <summary>
  4. /// 可实现表达式接口
  5. /// </summary>
  6. public interface IExpressionable<T> where T : class
  7. {
  8. /// <summary>
  9. /// 创建表达式
  10. /// </summary>
  11. /// <returns></returns>
  12. Expression<Func<T, bool>> CreateExpression();
  13. }
  14. }

我将创建Landa表达式的部分放在module中,这个module是和界面对应,接收界面传递参数,代码如下:

  1. public class RealEstateProjectCondition : IExpressionable<View_RealEstateProject>
  2. {
  3. /// <summary>
  4. /// 项目所在省份
  5. /// </summary>
  6. public string ProjectOfProvince { get; set; }
  7. /// <summary>
  8. /// 项目所在城市
  9. /// </summary>
  10. public string ProjectOfCity { get; set; }
  11. /// <summary>
  12. /// 项目业态名称
  13. /// </summary>
  14. public string ProjectFormatName { get; set; }
  15. /// <summary>
  16. /// 所属业务团队
  17. /// </summary>
  18. public string BusiGroup { get; set; }
  19. /// <summary>
  20. /// 项目所处阶段
  21. /// </summary>
  22. public string PrjStageCode { get; set; }
  23. /// <summary>
  24. /// 申请起始日期
  25. /// </summary>
  26. public DateTimeOffset? ApplyStartDate { get; set; }
  27. /// <summary>
  28. /// 申请起始日期
  29. /// </summary>
  30. public DateTimeOffset? ApplyEndDate { get; set; }
  31. /// <summary>
  32. /// 基金规模(亿元)上线
  33. /// </summary>
  34. public decimal? StartFundSize { get; set; }
  35. /// <summary>
  36. /// 基金规模(亿元)下线
  37. /// </summary>
  38. public decimal? EndFundSize { get; set; }
  39. /// <summary>
  40. /// 创建房地产投资查询条件表达式
  41. /// </summary>
  42. /// <returns></returns>
  43. public Expression<Func<View_RealEstateProject, bool>> CreateExpression()
  44. {
  45. ParameterExpression parameter = Expression.Parameter(typeof(View_RealEstateProject), "p");
  46. //项目类型编码
  47. ConstantExpression constantPrjTypeCode = Expression.Constant("A0BE01A2-1BE3-4AAE-8DE3-B84BB6B2A58A");
  48. MemberExpression memberPrjTypeCode = Expression.PropertyOrField(parameter, "PrjTypeCode");
  49. var query = Expression.Equal(memberPrjTypeCode, constantPrjTypeCode);
  50. //项目所在省份
  51. if (!string.IsNullOrEmpty(this.ProjectOfProvince))
  52. {
  53. ConstantExpression constantProjectOfProvince = Expression.Constant(this.ProjectOfProvince);
  54. MemberExpression memberProjectOfCity = Expression.PropertyOrField(parameter, "ProjectOfProvince");
  55. query = Expression.And(query, Expression.Equal(memberProjectOfCity, constantProjectOfProvince));
  56. }
  57. //项目所在城市
  58. if (!string.IsNullOrEmpty(this.ProjectOfCity))
  59. {
  60. ConstantExpression constantProjectOfCity = Expression.Constant(this.ProjectOfCity);
  61. MemberExpression memberProjectOfCity = Expression.PropertyOrField(parameter, "ProjectOfCity");
  62. query = Expression.And(query, Expression.Equal(memberProjectOfCity, constantProjectOfCity));
  63. }
  64. //项目业态名称
  65. if (!string.IsNullOrEmpty(this.ProjectFormatName))
  66. {
  67. ConstantExpression constantProjectFormatName = Expression.Constant(this.ProjectFormatName);
  68. MemberExpression memberProjectFormatName = Expression.PropertyOrField(parameter, "ProjectFormatName");
  69. query = Expression.And(query, Expression.Equal(memberProjectFormatName, constantProjectFormatName));
  70. }
  71. //所属业务团队
  72. if (!string.IsNullOrEmpty(this.BusiGroup))
  73. {
  74. ConstantExpression constantBusiGroup = Expression.Constant(this.BusiGroup);
  75. MemberExpression memberBusiGroup = Expression.PropertyOrField(parameter, "BusiGroup");
  76. query = Expression.And(query, Expression.Equal(memberBusiGroup, constantBusiGroup));
  77. }
  78. //项目所处阶段
  79. if (!string.IsNullOrEmpty(this.PrjStageCode))
  80. {
  81. ConstantExpression constantPrjStageCode = Expression.Constant(this.PrjStageCode);
  82. MemberExpression memberPrjStageCode = Expression.PropertyOrField(parameter, "PrjStageCode");
  83. query = Expression.And(query, Expression.Equal(memberPrjStageCode, constantPrjStageCode));
  84. }
  85. //申请开始时间
  86. if (this.ApplyStartDate.HasValue)
  87. {
  88. ConstantExpression constantApplyStartDate = Expression.Constant(this.ApplyStartDate.Value);
  89. MemberExpression memberApplyStartDate = Expression.PropertyOrField(parameter, "ApplyDate");
  90. query = Expression.And(query, Expression.GreaterThanOrEqual(memberApplyStartDate, constantApplyStartDate));
  91. }
  92. //申请结束时间
  93. if (this.ApplyEndDate.HasValue)
  94. {
  95. ConstantExpression constantApplyEndDate = Expression.Constant(this.ApplyEndDate.Value);
  96. MemberExpression memberApplyEndDate = Expression.PropertyOrField(parameter, "ApplyDate");
  97. query = Expression.And(query, Expression.LessThanOrEqual(memberApplyEndDate, constantApplyEndDate));
  98. }
  99. //投资规模(亿元)上线
  100. if (this.StartFundSize.HasValue)
  101. {
  102. ConstantExpression constantStartFundSize = Expression.Constant(this.StartFundSize.Value);
  103. MemberExpression memberStartFundSize = Expression.PropertyOrField(parameter, "FundSize");
  104. query = Expression.And(query, Expression.GreaterThanOrEqual(memberStartFundSize, constantStartFundSize));
  105. }
  106. //投资规模(亿元)下线
  107. if (this.EndFundSize.HasValue)
  108. {
  109. ConstantExpression constantEndFundSize = Expression.Constant(this.EndFundSize.Value);
  110. MemberExpression memberEndFundSize = Expression.PropertyOrField(parameter, "FundSize");
  111. query = Expression.And(query, Expression.LessThanOrEqual(memberEndFundSize, constantEndFundSize));
  112. }
  113. //版本结束时间
  114. ConstantExpression constantVesionEndTime = Expression.Constant(null);
  115. MemberExpression memberVesionEndTime = Expression.PropertyOrField(parameter, "VersionEndTime");
  116. query = Expression.And(query, Expression.Equal(memberVesionEndTime, constantVesionEndTime));
  117. //有效性
  118. ConstantExpression constantValidStatus = Expression.Constant(true);
  119. MemberExpression memberValidStatus = Expression.PropertyOrField(parameter, "ValidStatus");
  120. query = Expression.And(query, Expression.Equal(memberValidStatus, constantValidStatus));
  121. return Expression.Lambda<Func<View_RealEstateProject, bool>>(query, parameter);
  122. }
  123. }

这样我们的controller和service都非常的简单明了,把查询条件作为实体的一部分。

service代码:

  1. public List<View_RealEstateProject> LoadView_RealEstateProject(RealEstateProjectCondition condition)
  2. {
  3. using (var db = new InvestmentDbContext())
  4. {
  5. return db.View_RealEstateProject.Where(condition.CreateExpression()).ToList();
  6. }
  7. }

controller代码:

  1. [HttpPost, HttpGet]
  2. public IHttpActionResult LoadQueryResult(RealEstateProjectCondition condition)
  3. {
  4. return Json(_realEstabDasbordService.LoadView_RealEstateProject(condition));
  5. }

小结

关于动态创建Lamda表达式就给大家介绍到这,通过动态创建表达式非常方便实现高级查询,和拼接sql来说这

还是非常简单的,并且出错的几率大大降低,所以我没有采用他们类似功能的实现,所以说我们在实现某些需求的时

候需要我们好好考虑在下手写代码,能参考的东西不一定是最合适的,还需要我们自己探索一些,希望给大家带来帮

助。

http://blog.csdn.net/hao134838/article/details/51404151

动态创建Lambda表达式实现高级查询的更多相关文章

  1. C#动态创建lambda表达式

    /// <summary> /// 创建lambda表达式:p=>true /// </summary> /// <typeparam name="T&q ...

  2. 使用Expression动态创建lambda表达式

    using System;using System.Linq.Expressions;using System.Reflection; namespace Helper{ public class L ...

  3. 动态创建 Lambda 表达式

    首先我们看一个简单 Lambda 表达式的构成. i => i > 5 在这个表达式中,"i" 被称为 Parameter,"i > 5" 是 ...

  4. 动态组合lambda 表达式

    //记录实体集合—动态组合lambda 表达式 Expression<Func<AdEntity, bool>> thirdWhere = p => p.Observer ...

  5. easyui datagrid remoteSort的实现 Controllers编写动态的Lambda表达式 IQueryable OrderBy扩展

    EF 结合easy-ui datagrid 实现页面端排序 EF动态编写排序Lambda表达式 1.前端页面 var mainListHeight = $(window).height() - 20; ...

  6. 【转】EntityFramework动态组合Lambda表达式作为数据筛选条件,代替拼接SQL语句

    传统的操作数据库方式,筛选数据需要用StringBuilder拼接一大堆的WHERE子句. 在Entity Framework中,代码稍有不慎就会造成巨大性能消耗,如: using(var db=ne ...

  7. C#高级知识点概要(3) - 特性、自动属性、对象集合初始化器、扩展方法、Lambda表达式和Linq查询

    1.特性(Attributes) 特性(Attributes),MSDN的定义是:公共语言运行时允许你添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型.字段.方法 ...

  8. [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)

    声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...

  9. 动态构建Lambda表达式实现EF动态查询

    在使用Entity Framework做数据查询的时候,查询条件往往不是固定的,需要动态查询.可以通过动态构建Lamda表达式来实现动态查询. Lamda表达式 使用Lamda表达式可以很方便的按条件 ...

随机推荐

  1. 【java】开源工具包hutool

    开源工具包hutool GitHub地址:https://github.com/looly/hutool 项目主页:http://www.hutool.cn/

  2. CSS3:2D转换方法

    利用transform 可以实现旋转.缩放.倾斜.移动 属性有:translate.scale 移动: translateX(10px); //水平方向移动10px translateY(50px); ...

  3. python读写文件write和flush

    打开文件用open,该函数创建一个文件对象,这将用来调用与之关联的其他支持方式. file object = open(file_name [, access_mode][, buffering]) ...

  4. JPEG编码(一)

    JPEG编码介绍. 转自:http://blog.chinaunix.net/uid-20451980-id-1945156.html JPEG(Joint Photographic Experts ...

  5. 【Hadoop】HDFS冗余数据块的自动删除

    HDFS冗余数据块的自动删除 在日常维护hadoop集群的过程中发现这样一种情况: 某个节点由于网络故障或者DataNode进程死亡,被NameNode判定为死亡, HDFS马上自动开始数据块的容错拷 ...

  6. Spring中如何配置事务

    学过SSH的都知道,整合了SSH之后,SSH的经典增删改查案例业务逻辑层的代码就十分简单.基本上都是一句话的事. public void addUser(Webuserlogin user) { // ...

  7. 不删除记录的表CRUD的常见处置

    为什么不删除记录,因为这些记录只是暂时不用了,以后还是有可能会用到的,比如说统计:另外一些主键外键依赖级联删除的场合也不好真删的,容易批量删除.真删了就不容易恢复回来了. 一般做法是,增加一个avai ...

  8. Angular 学习笔记——$http

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  9. 倍福TwinCAT(贝福Beckhoff)基础教程3.1 TwinCAT如何编写简单的计算器

    把编写简单计算器作为入门的第一个范例程序,主要是因为比较简单,而且综合了HMI,数据类型,数据转换,PRG和FBD等功能块的混合等知识,个人认为还是比较适合用来快速上手的.由于是第一个范例,所以视频教 ...

  10. Laravel之Eloquent ORM访问器调整器及属性转换

    一.查询构建器的get方法 查询构建器的get方法返回了一个集合 $users = App\User::where('active', 1)->get(); foreach ($users as ...