LINQ Group By操作

假设我们需要从两张表中统计出热门商圈,这两张表内容如下:

  • 上表是所有政区,商圈中的餐饮个数,名为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及以上版本中均可以使用,它是立即执行,但是他们的作用相同,我们只需要传入转换的方法即可。

时间: 2024-10-27 14:15:32

LINQ Group By操作的相关文章

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

Linq特取操作之ElementAt,Single,Last,First源码分析 一:linq的特取操作 First/FirstOrDefault, Last/LastOrDefault, ElementAt/ElementAtOrDefault, Single/SingleOrDefault 二:First/FirstOrDefault 介绍 解释: 用于返回序列中的第一个值 异常: 如果当前集合没有值的话,如果你取第一个值,会抛出throw Error.NoElements();异常. pu

Linq之Join操作

1 摘要 文章通过一个简单的实例对Linq中的Join操作进行演示,并在文章的最后对Join操作相关知识点进行简单的总结. 2 实例演示 1) 新建数据库MyTestDB,在数据库中新建数据表tb_Class和tb_Student,两表的定义如下图所示.                                        图1  tb_Class的定义                                                                    

linq group join

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

python中模拟C#对应Linq的一些操作

也可以说是.net的Linq操作.python版本如果低于3.0不支持lambda,只能单独写函数传参,比较麻烦 先看看函数作为参数有没有问题: def TestFunc(): print "!!!" def Foo(func): func() def main(): Foo(TestFunc) #print !!! 经过测试打印出了"!!!",看来还是支持的 模拟一下linq的FirstOrDefault: def FirstOrDefault(collectio

linq group by max 多表链接实例

SELECT s.* FROM dbo.ERG_TipOffsInfo s, (SELECT Data,MAX(Createtime) max_Time FROM dbo.ERG_TipOffsInfo GROUP BY Data) t WHERE s.Data=t.Data AND s.CreateTime = t.max_Time AND s.TipOffsTypeId=2 ORDER BY s.Createtime DESC linq 改写代码 var list = from s in c

【转】Linq Group by

http://www.cnblogs.com/death029/archive/2011/07/23/2114877.html 1.简单形式: var q = from p in db.Products group p by p.CategoryID into g select g; 语句描述:Linq使用Group By按CategoryID划分产品. 说明:from p in db.Products 表示从表中将产品对象取出来.group p by p.CategoryID into g表示

Linq学习笔记---Linq to Xml操作

LINQ to XML的成员, 属性列表: 属性 说明 Document 获取此 XObject 的 XDocument  EmptySequence  获取空的元素集合  FirstAttribute  获取此元素的第一个属性  FirstNode  获取此节点的第一个子节点  HasAttributes  获取一个值,该值指示此元素是否至少具有一个属性  HasElements  获取一个值,该值指示此元素是否至少具有一个子元素  IsEmpty  获取一个值,该值指示此元素是否不包含内容

Linq To Xml操作XML增删改查

对XML文件的操作在平时项目中经常要运用到,比如用于存放一些配置相关的内容:本文将简单运用Linq TO Xml对XML进行操作,主要讲解对XML的创建.加载.增加.查询.修改以及删除:重点在于类XDocument.类XElement:本实例是在控制台程序运行,所以对加载的XML文件路径要注意,若XML文件不是代码自运创建时要设置其"复制到输出目录"-始终复制 1:首先看一下实例要加载的XML文件格式: <?xml version="1.0" encoding

linq一些简单操作

简单的Linq&Lamda语法:     (1) 简单的查询语句: Linq语法: var data=from a in db.Areas select a ;Lamda语法: var data=db.Areas;sql语法: string sqlStr=" SELECT * FROM Areas "; (2) 简单的WHERE语句: Linq语法: var data=from a in db.orderInfo where a.orderId > 20 select a