zoukankan      html  css  js  c++  java
  • 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及以上版本中均可以使用,它是立即执行,但是他们的作用相同,我们只需要传入转换的方法即可。

    原文链接

  • 相关阅读:
    代码中莫名其妙多出的空格
    hierarchyviewer偶然不能使用的解决方法
    HierarchyView的实现原理和Android设备无法使用HierarchyView的解决方法
    Android L Ripple的使用
    Android2.2 API —— ImageView
    android:tint
    Android特效--粒子效果之雨
    Android 简单的FC
    Google开源库-Volley
    Css总结
  • 原文地址:https://www.cnblogs.com/OpenCoder/p/10339546.html
Copyright © 2011-2022 走看看