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及以上版本中均可以使用,它是立即執行,但是他們的作用相同,我們只需要傳入轉換的方法即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM