假设我们需要从两张表中统计出热门商圈,这两张表内容如下:
- 上表是所有政区,商圈中的餐饮个数,名为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及以上版本中均可以使用,它是立即执行,但是他们的作用相同,我们只需要传入转换的方法即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!