首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

LINQ 學習筆記:GroupBy 分組操作完整指南 (鍵選擇器、元素選擇器、自訂比較器、多鍵分組)

     編輯:關於SqlServer

GroupBy 將扁平序列轉換為分組序列 (IEnumerable<IGrouping<TKey, TElement>>),對應 SQL GROUP BY。本文詳細解析參數組合、延續查詢、複合鍵、自訂比較器與 LINQ to SQL 特有優化。

核心語法與參數


IEnumerable> GroupBy(
    this IEnumerable source,
    Func keySelector,           // 必填:分組鍵
    Func elementSelector,   // 選填:分組內元素投影
    IEqualityComparer comparer           // 選填:鍵比較邏輯
)

基礎範例:依副檔名分組檔案


string[] files = Directory.GetFiles(@"c:\temp");
var query = files.GroupBy(f => Path.GetExtension(f));

// 列舉結果
foreach (var group in query) {
    Console.WriteLine("Extension: " + group.Key);
    foreach (var file in group) Console.WriteLine(" - " + file);
}

元素選擇器:投影分組內元素


// 將檔名轉大寫,分組鍵仍為副檔名
var query = files.GroupBy(
    f => Path.GetExtension(f),   // keySelector
    f => f.ToUpper()             // elementSelector
);
// 分組結果鍵相同,但元素為大寫檔名

注意: elementSelector 與 keySelector 獨立,不影響分組邏輯。

排序與分組順序

GroupBy **不保證** 分組順序,僅保留原序列中首次出現鍵的相對順序。需排序請顯式 OrderBy:


var sorted = files
    .GroupBy(f => Path.GetExtension(f), f => f.ToUpper())
    .OrderBy(g => g.Key); // 依副檔名排序

查詢運算式語法


// 基本分組 (以 group 結尾)
var q1 = from f in files
         group f.ToUpper() by Path.GetExtension(f);

// 延續查詢 (group ... into):後續可接 where/orderby/select
var q2 = from f in files
         group f.ToUpper() by Path.GetExtension(f) into g
         where g.Count() < 5          // 篩選分組
         orderby g.Key
         select g;

// 僅需聚合結果 (丟棄子序列)
string[] votes = { "Bush", "Gore", "Gore", "Bush", "Bush" };
var winner = (from v in votes
              group v by v into g
              orderby g.Count() descending
              select g.Key).First(); // "Bush"

多鍵分組 (複合鍵)

使用**匿名型別**建立複合鍵,編譯器自動實作 Equals/GetHashCode:


// 依首字母 + 長度 分組
var q = from n in names
        group n by new { FirstLetter = n[0], Length = n.Length };

自訂比較器

僅限 LINQ to Objects (本地查詢)。通常調整 keySelector 即可 (如 ToUpper()),極少需自訂 IEqualityComparer:


// 不區分大小寫分組 (等效於 keySelector: n => n.ToUpper())
var q = names.GroupBy(n => n, StringComparer.CurrentCultureIgnoreCase);

LINQ to SQL 中的 GroupBy 優化

若實體間有**導航屬性** (關聯),往往不需要顯式 GroupBy:


// 找出訂單數 >= 2 的客戶 (利用導航屬性 Purchases)
var q = from c in ctx.Customers
        where c.Purchases.Count >= 2
        select c.Name + " has made " + c.Purchases.Count + " purchases";

// 年度銷售總額 (需 GroupBy)
var q = from p in ctx.Purchases
        group p.Price by p.Date.Year into salesByYear
        select new { Year = salesByYear.Key, TotalValue = salesByYear.Sum() };
善用導航屬性可簡化查詢,但彙總統計 (如年度總額) 仍需 GroupBy。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved