linq 对Sum()函数的支持
首先看一段SQL语句:
SELECT SUM(TASKAPPR) AS APPRCOUNT, SUM(TASKLOCKED) AS LOCKEDCOUNT, SUM(TASKCHECKED) AS CHECKEDCOUNT FROM ( SELECT (CASE WHEN ISAPPR =1 THEN 1 ELSE 0 END) AS TASKAPPR, (CASE WHEN ISLOCKED =1 THEN 1 ELSE 0 END) AS TASKLOCKED, (CASE WHEN ISCHECKED =1 THEN 1 ELSE 0 END) AS TASKCHECKED FROM TASK) AS TEMP
上面是对一个叫Task表的三个bit类型的字段进行数据统计,用到了三个case when 来排除空值,然后放到一个临时表里面再进行sum查询。 当然这只是简单的一些,估计在工作中会遇到到多个表连接,多个条件过滤再进行相关字段统计,那么估计代码下来,差不多也得个四五十行,如果你用的数据驱动是Ef,那么这个时候我估计你会先下意识的思考一下用Linq 或者Lamda表达式如何写,毕竟我想你前端的条件都已经封装给了Expression<Func<T,bool>>,你一定不想让你的程序中再出现红色的sql过滤条件。但是回过头来你又马上意识到用linq实现这样的业务场景也没那么容易,尤其是需要很多的判断和很多的sum(),更加坑爹的是按照以上sql的执行逻辑去写相应的linq语句的时候,你会很快发现进入到了死胡同。
Tasks.Select (t=>new{ TASKAPPR=t.IsAppr==true?1:0, TASKLOCKED=t.IsLocked==true?1:0, TASKCHECKED=t.IsChecked==true?1:0, })
写到了上面你已经完全不知道该如何执行三个Sum函数,搜了半天攻略,发现面临多个Sum的时候都是进行分组group by (),而咱们这里完全不需要group By。到此,陷入死胡同,眼看快要下班,就开始用自己炉火纯青的技术编写了一个sql 存储过程。然后交工完成。
但是这件事情一直就在我心中留下了一些遗憾,虽然说存储过程的执行效率要比Linq to Entity 快点,但是sql语句属于执行语句,不分大小写,后期维护特别艰难,而linq却属于强类型代码,更容易维护拓展,再加上net4.5已经对Linq的性能做了一些优化,用linq还是ADO.NET执行之间的性能对比已经显得意义不大。终于有一天,看到国外的某一程序员解决了这一问题,代码如下:
from task in Tasks // where express group task by 1 into g select new { TASKAPPR=g.Sum(t.IsAppr==true?1:0), TASKLOCKED=g.Sum(t.IsLocked==true?1:0), TASKCHECKED=g.Sum(t.IsChecked==true?1:0) }
这里巧妙的利用了group by 语句。不再是group by 某一个或者多个字段进行分组。达成的效果与上面的sql语句一致。
上面代码利用的事LinPad,所以不必纠结写法上的差异。
posted on 2014-03-28 10:12 Richard__Lee 阅读(877) 评论(0) 编辑 收藏 举报