linq to sql之组装where条件下的'或'语句
之前遇到过类似的需求,即前台传入几个过滤条件,后台动态组装where。
例如,前台传入name='张三',age=10, 其余的字段,类似email,QQ之类的本次查询时不做过滤。
用linq to sql来组装where语句非常方便。
var f= db.Users.Where(x => true);
if(!string.IsNullOrWhiteSpace(name))
f= f.Where(x=>x.Name == name);
if(age != null)
f= f.Where(x=>x.Age == age);
var data = f.ToList();
今天碰到另一种情况。状态的多种可能性。用户的注册邮箱有多个状态(用int表示):未验证null,无效-1,有效0,退订-2,查看(>0的值)等。前台过滤时,可能勾选多个状态,例如未验证 或 有效 或 查看。用后台的where表示,就是:
Where(x => x.EmailState == null || x.EmailState == || x.EmailState > )
问题出现了。这里有五种状态,每个状态有前台选中和未选中两种情况,组合的情况最多有2^5 = 32种。用32个if来解决这里的问题,不是不可以,只是代码会显得很笨重,而且扩展性很差,如果以后出现第六个、第七个状态......T_T...T_T
首先想到的,能不能像上面的where组装那样实现。答案是不行。上面的where很明显是逻辑and运算。而这里应该是单个where情况下的or运算。
解决思路:用Func<Users,bool>来表示每一个邮箱状态对应的过滤语句。对勾选的每一个状态,对它们的过滤语句执行'||'运算。
filter1(x) || filter2(x) || filter3(x)...
代码方案一:
Func<Users, bool> filter = x => false;
if (chkEmailUnverify.Checked) filter = x => filter(x) || x.SendMail == null;
if (chkEmailUnsubscribe.Checked) filter = x => filter(x) || x.SendMail == -;
if (chkEmailInvalid.Checked) filter = x => filter(x) || x.SendMail == -;
if (chkEmailValid.Checked) filter = x => filter(x) || x.SendMail == ;
if (chkEmailOpen.Checked) filter = x => filter(x) || (x.SendMail.HasValue && x.SendMail.Value > );
对勾选的每一个状态,在之前的Func<Users,bool>基础上执行||运算。理论上来讲应该行得通,但是实际上调试的时候发现,只要超过两个勾选,就会报错:

提示堆栈溢出。呃...对这类问题一直比较怵,对clr不了解。只能做猜测:因为filter本身就是代理,而代理的执行有延迟的特性,所以这里filter = x => filter(x)...可能会出现无限向下发展的情况。寻求曲线解决。
代码方案二:
Func<Users, bool> filter = x => true;
List<Func<int?, bool>> list = new List<Func<int?, bool>>() { x => false };
if (chkEmailUnverify.Checked) list.Add(x => x == null);
if (chkEmailValid.Checked) list.Add(x => x == );
if (chkEmailOpen.Checked) list.Add(x => x > );
if (chkEmailUnsubscribe.Checked) list.Add(x => x == -);
if (chkEmailInvalid.Checked) list.Add(x => x == -); filter = x => list.Select(c => c(x.SendMail)).Aggregate((a, b) => a || b);
好吧,我承认只是在之前的那个思路基础上加了一个外壳。壳的主要思想是避免出现filter = x => filter(x) || x.Shield == 'value'。
可能上面的考虑有些道理,这次的方案通过了编译,也取得了我要的结果。大功告成~o(∩_∩)o
调用时的代码:
var f= db.Users.Where(filter);
如有错误,欢迎留言指导。
为MH370祈福~
linq to sql之组装where条件下的'或'语句的更多相关文章
- LINQ之路10:LINQ to SQL 和 Entity Framework(下)
在本篇中,我们将接着上一篇“LINQ to SQL 和 Entity Framework(上)”的内容,继续使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术 ...
- LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新
原文:LINQ To SQL在N层应用程序中的CUD操作.批量删除.批量更新 0. 说明 Linq to Sql,以下简称L2S. 以下文中所指的两层和三层结构,分别如下图所示: 准确的说,这里 ...
- 深入理解 LINQ to SQL 生成的 SQL 语句
Ø 简介 在 C# 中与数据交互最常用的语句就是 LINQ 了,而 LINQ to SQL 是最直接与数据库打交道的语句,它可以根据 LINQ 语法生成对应的 SQL 语句,在数据库中去执行.本文主 ...
- LINQ之路 9:LINQ to SQL 和 Entity Framework(上)
在上一篇中,我们从理论和概念上详细的了解了LINQ的第二种架构“解释查询”.在这接下来的二个篇章中,我们将使用LINQ to SQL和Entity Framework来实践“解释查询”,学习这些技术的 ...
- Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询
原文:Linq to Sql:N层应用中的查询(下) : 根据条件进行动态查询 如果允许在UI层直接访问Linq to Sql的DataContext,可以省去很多问题,譬如在处理多表join的时候, ...
- LINQ系列:LINQ to SQL Where条件
1. 单一条件查询 var expr = context.Products .Where(p => p.ProductName == "LINQ to SQL"); SELE ...
- Linq to sql 实现多条件的动态查询(方法一)
/// <summary> /// Linq to sql 多字段动态查询 /// </summary> /// <returns></returns> ...
- LINQ to SQL语句(7)之Exists/In/Any/All/Contains
适用场景:用于判断集合中元素,进一步缩小范围. Any 说明:用于判断集合中是否有元素满足某一条件:不延迟.(若条件为空,则集合只要不为空就返回True,否则为False).有2种形式,分别为简单形式 ...
- 年终巨献 史上最全 ——LINQ to SQL语句
LINQ to SQL语句(1)之Where 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的子句.Where操 ...
随机推荐
- 浅谈cocos2dx(18) 中工厂模式
----我的生活.我的点点滴滴! ! cocos2d-x中也有工厂模式.何为工厂模式,顾名思义就是用来产生产品的,工厂就是用来创建其它类对象的类,我们把这个创建其它类对象的类叫做工厂类.而这些被创建的 ...
- Java – How to convert Array to Stream
Java – How to convert Array to Stream 1. Object Arrayspackage com.mkyong.java8; import java.util.Arr ...
- 利用nginx搭建RTMP视频点播、直播、HLS服务器
开发环境 Ubuntu 14.04 server nginx-1.8.1 nginx-rtmp-module nginx的服务器的搭建 安装nginx的依赖库 sudo apt-get update ...
- Android Studio 1.1.0 向导页(首页) 解析,以及版本控制 (SVN 和 GIT 的检出)
使用Android Studio首先要理清楚, Android Studio 的 project 相当于Eclipse的 Workspace Android Studio 的 module 相当于E ...
- struts2(六) 文件上传和下载
前面对文件下载提过一点点,这里正好要讲文件上传,就放在一起在说一遍. --WH 一.单文件上传 在没学struts2之前,我们要写文件上传,非常麻烦,需要手动一步步去获取表单中的各种属性,然后在进行相 ...
- 【Unity】2.10 利用VS2015编辑Unity的C#脚本
分类:Unity.C#.VS2015 创建日期:2016-03-31 一.简介 用VS2015编辑C#脚本时,如果让其"显示所有文件",就会看到VS2015解决方案资源管理器中项目 ...
- 【Unity】2.7 检视器(Inspector)
分类:Unity.C#.VS2015 创建日期:2016-03-31 一.简介 Unity中的游戏是以包含网格.脚本.声音或灯光 (Lights) 等其他图形元素的多个游戏对象 (GameObject ...
- HTTPS简单原理介绍
为什么需要https HTTP是明文传输的,也就意味着,介于发送端.接收端中间的任意节点都可以知道你们传输的内容是什么.这些节点可能是路由器.代理等. 举个最常见的例子,用户登陆.用户输入账号,密码, ...
- 【小白的CFD之旅】24 稳态和瞬态
小白最近在练习案例的时候,对稳态和瞬态的问题,产生了一些疑问.譬如说,为什么有的案例用稳态,而有的案例用瞬态?有时候相同的案例既可以用稳态也可以用瞬态,而有的案例却只能用瞬态计算?小白决定找小牛师兄问 ...
- Cloud Resource
Cloud Public Cloud Aliyun AWS Azure Cloud Stack SDN指南 DNS:Band Private Cloud DC/OS OpenStack Hybrid ...