ef 动态条件 查询 组合查询 配置 expession 拼接参考
来源:互联网 发布:医疗数据投融资 编辑:程序博客网 时间:2024/04/29 08:20
转自:http://blog.csdn.net/tastelife/article/details/7333513
Lambda表达式 c# 经验谈:巧用Expression表达式 解决类似于sql中 select in 的查询(适合于中小型项目)
我们在项目经常会碰到一些特殊需求 例如下拉框是复选的,查询条件是根据下拉框中复选项进行拼接
看到此图后大家肯定会说,这很简单嘛
将所有的选项 拼成“'1-3','5-9'” 然后放到 in 的字句后面,一查就出来了。
这样做的确在逻辑上没有问题,可是大家有没有想过这个问题,过度的和业务耦合虽然能够解决
现在的需求但是却牺牲了代码优雅和可维护性
其实本文的目的是想利用Expression表达式在linq查询中实现一个优雅的解决方案,
同时也会给大家一个用Expression去拼接sql的思路
先上代码
public static Expression<Func<T, bool>> GetConditionExpression<T>(string[] options, string fieldName) { ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=> Expression expression = Expression.Constant(false); foreach (var optionName in options) { Expression right = Expression.Call ( Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法
s Expression.Constant(optionName) // .Contains(optionName) ); expression = Expression.Or(right, expression);//c.DataSourceName.contain("") || c.DataSourceName.contain("") } Expression<Func<T, bool>> finalExpression = Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left }); return finalExpression; }
我想用逆推的方式说明下这段代码,其实我们查询的目的要实现这样的效果 , someList.where(c=>c.Name.contains("someName")||c.Name.Contains("someName")||...)
1. 首先我们要确定返回什么样的表达式,根据经验.where后面是需要一个Expression<Func<T, bool>> 这样的一个表达式,所以方法的返回类型已经能确定下来了
2. 接下来的任务是拼接类似于c=>c.Name.Contains("") 这样的表达式,按照自左向右的原则,左侧表达式参数c很好理解 就是T,那么这个表达式的参数也就搞定了,
可以用Expression.Parameter方法来实现,该方法目的是将类型反射并且映射给表达式中的匿名变量 “c” (也可以理解成将参数常量封装成表达式)
3. 接着是表达式右侧的拼接
再次仔细看下这段代码
Expression right = Expression.Call
(
Expression.Property(left, typeof(T).GetProperty(fieldName)), //c.DataSourceName 首先是反射获取c的一个属性
typeof(string).GetMethod("Contains",new Type[] { typeof(string) }),// 声明一个string.Contains的方法 c.DataSourceName.Contains() 反射使用.Contains()方法
Expression.Constant(optionName) // c.DataSourceName.Contains(optionName) 封装常量
);
为什么要使用Expression.Call ?
(因为c.Name.contains 属于string.contains()这个方法所以我们必须将该方法封装成表达式,Expression.Call的功能就是将方法封装成表达式)
这时候大家会问contains什么呢? 当然常量option虽然是string类型,但是仍需封装成表达式,Expression.Constant(optionName) 起到了封装常量的作用
于是c=>c.属性.Contains(常量) 这个表达式搞定,可是还是有问题:怎么加上“||” ,聪明的你已经有了答案,Expression.Or()
4 最后一步当然非常关键,就像产品需要通过流水线进行包装组合,表达式也不例外:
Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left });
对于整个表达式来说,左侧是参数表达式(ParameterExpression),Expression.Lambda就是=>符号,就右侧表达式和参数表达式通过lambda符号进行组合,搞定
这样的话,你只需传入一个字符串数组就能在Linq中实现类似于sql中select in 的效果了,
很多朋友肯定会问,既然能够用自定义表达式搞定,那么可不可以将表达式的思路用于拼接sql?
答案是肯定的。但是如果业务逻辑非常复杂,而且难以把握,还是建议用ado 配合存过实现
- ef 动态条件 查询 组合查询 配置 expession 拼接参考
- linq to ef 动态查询条件
- linq 动态拼接查询条件 扩展方法
- linq 动态拼接查询条件 扩展方法
- 根据条件查询动态拼接sql语句
- 动态拼接LINQ查询条件的解决方案
- 动态sql语句拼接查询条件
- 查询条件的拼接
- mybatis拼接条件查询
- mybatis拼接查询条件
- hibernate 多条件组合查询 之 sql 拼接
- hibernate 多条件组合查询之sql拼接
- hibernate 多条件组合查询之sql拼接
- hibernate 多条件组合查询之sql拼接
- C# MongoDB 多条件动态组合查询
- EF中一种简单的多条件动态查询方法
- EF实现分页查询+条件查询+排序
- 组合条件查询
- Java设计模式之原型模式
- Pig系统分析(6)-从Physical Plan到MR Plan再到Hadoop Job
- poj1029(找假硬币)模拟
- spring定时任务applicationContext.xml中配置
- maven+springMVC+mybatis+junit详细搭建过程
- ef 动态条件 查询 组合查询 配置 expession 拼接参考
- ZOJ 1154 Niven Numbers
- NBUT Minecraft Server Bug
- PHP中CKEditor和CKFinder配置
- 通过类String看拷贝构造函数,赋值函数的作用和区别
- 【SkinUI实例】仿QQ界面设计第三十二课
- z-index的兼容性问题
- 关于产品的一些思考——淘友天下之脉脉
- nginx 整合tomcat 配置 学习笔记