在上篇文章 .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中将两个集合合并有两个方法,UnionConcat,其中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操作的更多相关文章

  1. LINQ Group By操作(转载)

    假设我们需要从两张表中统计出热门商圈,这两张表内容如下: 上表是所有政区,商圈中的餐饮个数,名为FoodDistrict 下表是所有政区,商圈中的SPA个数,名为SPADistrict 现在要把这两张 ...

  2. [C#] 进阶 - LINQ 标准查询操作概述

    LINQ 标准查询操作概述 序 “标准查询运算符”是组成语言集成查询 (LINQ) 模式的方法.大多数这些方法都在序列上运行,其中的序列是一个对象,其类型实现了IEnumerable<T> ...

  3. LINQ系列:LINQ to XML操作

    LINQ to XML操作XML文件的方法,如创建XML文件.添加新的元素到XML文件中.修改XML文件中的元素.删除XML文件中的元素等. 1. 创建XML文件 string xmlFilePath ...

  4. Linq特取操作之ElementAt,Single,Last,First源码分析

    Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, Eleme ...

  5. .NET LINQ基本查询操作

    获取数据源      在 LINQ 查询中,第一步是指定数据源.像在大多数编程语言中一样,在 C# 中,必须先声明变量,才能使用它.在 LINQ 查询中,最先使用 from 子句的目的是引入数据源 ( ...

  6. linq group join

    本篇介绍Linq的Group和Join操作,继续使用<Linq 学习(3) 语法结构>中介绍的数据源. GroupGroup是进行分组操作,同SQL中的Group By类似.原型如下: p ...

  7. C# LINQ学习笔记二:LINQ标准查询操作概述

    本笔记摘抄自:https://www.cnblogs.com/liqingwen/p/5801249.html,记录一下学习过程以备后续查用. “标准查询运算符”是组成语言集成查询 (LINQ) 模式 ...

  8. 【转】Linq Group by

    http://www.cnblogs.com/death029/archive/2011/07/23/2114877.html 1.简单形式: var q = from p in db.Product ...

  9. linq group by子句

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

随机推荐

  1. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  2. MIP改造常见问题二十问

    在MIP推出后,我们收到了很多站长的疑问和顾虑.我们将所有疑问和顾虑归纳为以下二十个问题,希望对大家理解 MIP 有帮助. 1.MIP 化后对其他搜索引擎抓取收录以及 SEO 的影响如何? 答:在原页 ...

  3. 【流量劫持】躲避 HSTS 的 HTTPS 劫持

    前言 HSTS 的出现,对 HTTPS 劫持带来莫大的挑战. 不过,HSTS 也不是万能的,它只能解决 SSLStrip 这类劫持方式.但仔细想想,SSLStrip 这种算劫持吗? 劫持 vs 钓鱼 ...

  4. 【前端性能】高性能滚动 scroll 及页面渲染优化

    最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优化. 主要内容包括了为何需要优化滚动事件,滚动与页面渲染的 ...

  5. 匹夫细说C#:庖丁解牛迭代器,那些藏在幕后的秘密

    0x00 前言 在匹夫的上一篇文章<匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置>的最后,匹夫以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够过瘾,很多需要说清楚 ...

  6. Js 原型和原型链

    Js中通过原型和原型链实现了继承 Js对象属性的访问,首先会查找自身是否拥有这个属性 如果查到,则返回属性值,如果找不到,就会遍历原型链,一层一层的查找,如果找到就会返回属性值 直到遍历完Object ...

  7. [APUE]系统数据文件与信息

    一.口令文件 UNIX口令文件包含下表中的各个字段,这些字段包含在 由于历史原因,口令文件是/bin/passwd,而且是一个文本文件,每一行都包括了上表中的七个字段,字段之间用":&quo ...

  8. 120项改进:开源超级爬虫Hawk 2.0 重磅发布!

    沙漠君在历时半年,修改无数bug,更新一票新功能后,在今天隆重推出最新改进的超级爬虫Hawk 2.0! 啥?你不知道Hawk干吗用的? 这是采集数据的挖掘机,网络猎杀的重狙!半年多以前,沙漠君写了一篇 ...

  9. [.NET] C# 知识回顾 - Event 事件

    C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...

  10. LoadRunner函数百科叒叒叒更新了!

    首先要沉痛通知每周四固定栏目[学霸君]由于小编外派公干,本周暂停. 那么这周就由云层君来顶替了,当然要要说下自己做的内容啦,DuangDuang! <LoadRunner函数百科>更新通知 ...