LINQ Group By操作
在上篇文章 .NET应用程序与数据库交互的若干问题 这篇文章中,讨论了一个计算热门商圈的问题,现在在这里扩展一下,假设我们需要从两张表中统计出热门商圈,这两张表内容如下:
- 上表是所有政区,商圈中的餐饮个数,名为FoodDistrict
- 下表是所有政区,商圈中的SPA个数,名为SPADistrict
现在要把这两张表,根据政区和商圈合并,然后相加Counts,根据Counts的总大小排序,统计热门商圈和热门政区。

在这里仅讨论合并的问题,以演示在SQLServer和C#中LINQ的实现方法:
通常,我们可以直接通过在SQLServer里面首先通过Union All,然后再通过GroupBy语句来执行查询操作即可满足要求,过程如下:
SELECT d.CityLocationId ,
d.CityLocationName ,
d.BusinessDistrctID ,
d.BusinessDistrctName ,
SUM(Counts) AS Counts
FROM ( SELECT *
FROM FoodDistrict
UNION ALL
SELECT *
FROM SPADistrict
) d
GROUP BY d.CityLocationId ,
d.CityLocationName ,
d.BusinessDistrctID ,
d.BusinessDistrctName
ORDER BY Counts DESC
执行结果为:

这里面需要注意的是,Union和Union All的区别,Union会对相同的记录去重,所以这里采用的是Union All,另外Union或者Union All的两个字表或者查询中,不能够有Order By子句。一般是Union之后再进行Order By。
但是有些时候,以上两张表可能存在与不同的数据库中,或者即使存在同一个数据库中,业务逻辑方面也不应该都放到数据库中,否则容易会使得数据库性能成为瓶颈。所以在某些时候,以上操作可能需要移到业务逻辑中处理。
在C#中,我们可能会先取回两个List实体,这两个实体分别从数据库中获得,在C#中,我们使用LINQ语句的聚合,分组也能实现SQLServer类似的功能。
private List<BusinessDistrictWithCountModel> CombineDistrict(List<BusinessDistrictWithCountModel> foodBusinessDistrict,
List<BusinessDistrictWithCountModel> spaBusinessDistrict)
{
List<BusinessDistrictWithCountModel> result;
result = new List<BusinessDistrictWithCountModel>();
result = foodBusinessDistrict.Concat(spaBusinessDistrict).
GroupBy(x => new
{
x.CityLocationID,
x.CityLocationName,
x.BusinessDistrctID,
x.BusinessDistrctName
})
.Select(g=> new BusinessDistrictWithCountModel
{
CityLocationID = g.Key.CityLocationID,
CityLocationName = g.Key.CityLocationName,
BusinessDistrctID = g.Key.BusinessDistrctID,
BusinessDistrctName = g.Key.BusinessDistrctName,
ProductCount = g.Sum(a => a.ProductCount)
})
.OrderByDescending(x => x.ProductCount)
.ToList();
return result;
}
在LINQ中将两个集合合并有两个方法,Union和Concat,其中Union会对集合中相同的元素进行去重,而Concat则不会。这两个关键字分别对应SQLServer中的Union和Union All。
Linq中的GroupBy和SQLServer中的GoupBy也类似,将需要Group的字段放到一个匿名对象里,然后在紧接着的Select中,我们可以从key中拿到Group里的字段,然后还可以进行一些诸如Sum,Count等统计操作。
另外,在C#中将一个集合对象转换为另外一个集合对象的时候,可以使用Select或者ConvertAll这两个关键字,Select是LINQ里面的扩展方法,对于任何实现IEnumerable<>泛型接口的对象都可以使用,在.NET 3.5及以上平台上支持,并且和其他LINQ操作符一样,他是延迟执行(lazy evaluation)的;而ConvertAll则是List<>对象的方法,在.NET 2.0及以上版本中均可以使用,它是立即执行,但是他们的作用相同,我们只需要传入转换的方法即可。
LINQ Group By操作的更多相关文章
- LINQ Group By操作(转载)
假设我们需要从两张表中统计出热门商圈,这两张表内容如下: 上表是所有政区,商圈中的餐饮个数,名为FoodDistrict 下表是所有政区,商圈中的SPA个数,名为SPADistrict 现在要把这两张 ...
- [C#] 进阶 - LINQ 标准查询操作概述
LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...
- LINQ系列:LINQ to XML操作
LINQ to XML操作XML文件的方法,如创建XML文件.添加新的元素到XML文件中.修改XML文件中的元素.删除XML文件中的元素等. 1. 创建XML文件 string xmlFilePath ...
- Linq特取操作之ElementAt,Single,Last,First源码分析
Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, Eleme ...
- .NET LINQ基本查询操作
获取数据源 在 LINQ 查询中,第一步是指定数据源.像在大多数编程语言中一样,在 C# 中,必须先声明变量,才能使用它.在 LINQ 查询中,最先使用 from 子句的目的是引入数据源 ( ...
- linq group join
本篇介绍Linq的Group和Join操作,继续使用<Linq 学习(3) 语法结构>中介绍的数据源. GroupGroup是进行分组操作,同SQL中的Group By类似.原型如下: p ...
- C# LINQ学习笔记二:LINQ标准查询操作概述
本笔记摘抄自:https://www.cnblogs.com/liqingwen/p/5801249.html,记录一下学习过程以备后续查用. “标准查询运算符”是组成语言集成查询 (LINQ) 模式 ...
- 【转】Linq Group by
http://www.cnblogs.com/death029/archive/2011/07/23/2114877.html 1.简单形式: var q = from p in db.Product ...
- linq group by子句
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
随机推荐
- Be Better:遇见更好的自己-2016年记
其实并不能找到好的词语来形容过去的一年,感觉就如此平淡的过了!没有了毕业的稚气,看事情淡了,少了一丝浮躁,多了一分认真.2016也许就是那句话-多读书,多看报,少吃零食多睡觉,而我更愿意说--Be B ...
- 预览github里面的网页或dome
1.问题所在: 之前把项目提交到github都可以在路径前面加上http://htmlpreview.github.io/?来预览demo,最近发现这种方式预览的时候加载不出来css,js(原因不详) ...
- XML技术之DOM4J解析器
由于DOM技术的解析,存在很多缺陷,比如内存溢出,解析速度慢等问题,所以就出现了DOM4J解析技术,DOM4J技术的出现大大改进了DOM解析技术的缺陷. 使用DOM4J技术解析XML文件的步骤? pu ...
- .Net Core上也可以使用的二维码组件
我Fork了QRCoder,并且兼容了.Net Core,图形库用的是ZKWeb.System.Drawing Github: https://github.com/zkweb-framework/Q ...
- Openfiler配置RAC共享存储
将 Openfiler 用作 iSCSI 存储服务器,主要操作步骤如下: 1.设置 iSCSI 服务 2.配置网络访问 3.指定物理存储器并对其分区 4.创建新的卷组 5.创建所有逻辑卷 6.为每个逻 ...
- Autofac - 生命周期
实例生命周期决定在同一个服务的每个请求的实例是如何共享的. 当请求一个服务的时候,Autofac会返回一个单例 (single instance作用域), 一个新的对象 (per lifetime作用 ...
- 【uwp】浅谈China Daily 中划词翻译的实现
学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...
- Linux命令【第一篇】
1.创建一个目录/data 记忆方法:英文make directorys缩写后就是mkdir. 命令: mkdir /data 或 cd /;mkdir data #提示:使用分号可以在一行内分割两个 ...
- linux下 lvm 磁盘扩容
打算给系统装一个oracle,发现磁盘空间不足.在安装系统的时候我选择的是自动分区,系统就会自动以LVM的方式分区.为了保证系统后期的可用性,建议所有新系统安装都采用LVM,之后生产上的设备我也打算这 ...
- SpringMVC(关于HandlerMapping执行流程原理分析)
请求过来先碰见中央调度器(前端调度器) //Determine handler for the current request; 对当前请求决定交给哪个handler, 当前请求地址过来 处理器执行链 ...