LINQ Group By操作

时间:2021-11-28 16:00:22

在上篇文章 .NET应用程序与数据库交互的若干问题 这篇文章中,讨论了一个计算热门商圈的问题,现在在这里扩展一下,假设我们需要从两张表中统计出热门商圈,这两张表内容如下:

  • 上表是所有政区,商圈中的餐饮个数,名为FoodDistrict
  • 下表是所有政区,商圈中的SPA个数,名为SPADistrict

现在要把这两张表,根据政区和商圈合并,然后相加Counts,根据Counts的总大小排序,统计热门商圈和热门政区。

LINQ Group By操作

在这里仅讨论合并的问题,以演示在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

执行结果为:

LINQ Group By操作

这里面需要注意的是,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. &lbrack;C&num;&rsqb; 进阶 - 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&comma;Single&comma;Last&comma;First源码分析

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

  5. &period;NET LINQ基本查询操作

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

  6. linq group join

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

  7. C&num; 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. Angular JS的依赖注入

    依赖注入是一个在组件中给出的替代了硬的组件内的编码它们的依赖关系的软件设计模式.这减轻一个组成部分,从定位的依赖,依赖配置.这有助于使组件可重用,维护和测试. AngularJS提供了一个至高无上的依 ...

  2. 【UOJ &num;150】【NOIP 2015】运输计划

    http://uoj.ac/problem/150 用树链剖分求lca,二分答案树上差分判断. 时间复杂度$O(nlogn)$,n,m同阶. #include<cstdio> #inclu ...

  3. CSS3&lowbar;实现圆角效果box-shadow

    1.outline的直角与圆角 来给个div: <div class="use-outline"></div> 来再给个样式: .use-outline{ ...

  4. iOS UICollectionView之二(垂直滚动)

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

  5. Java程序员面试宝典1 ---Java基础部分(该博文为原创,转载请注明出处)

    (该博文为原创,转载请注明出处   http://www.cnblogs.com/luyijoy/  by白手伊凡) 1.    基本概念 1)         Java为解释性语言,运行过程:程序源 ...

  6. bzoj1040

    论环形dp的重要! 其实这个环比较简单,稍微分析一下就知道, 这是一个简单环,并且每个联通块里只含有一个. 我觉得把处理环的关键,就是要找出环形和线形(树形)有什么区别. 如果我们从某处断开的做dp的 ...

  7. 【类与对象】--------java基础学习第六天

    类与对象 1. 对于面向对象的开发来讲也分为三个过程: OOA(面向对象分析) OOD(面向对象设计) OOP(面向对象编程) 2. 面向对象的基本特征 2.1. 封装:保护内部操作(属性,方法)不被 ...

  8. 2018 HDU多校第四场赛后补题

    2018 HDU多校第四场赛后补题 自己学校出的毒瘤场..吃枣药丸 hdu中的题号是6332 - 6343. K. Expression in Memories 题意: 判断一个简化版的算术表达式是否 ...

  9. JavaScript 示例

    JavaScript 示例 <html lang="en"> <head> <meta charset="UTF-8"> & ...

  10. P1593 因子和

    P1593 因子和新算法:#define ni 逆元先质因数分解,(1+p1^1+p1^2...p1^x)*(1+p2^1+p2^2...p2^x)然后套等比数列公式就可以了. #include&lt ...