程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> LINQ學習筆記:聚合方法

LINQ學習筆記:聚合方法

編輯:關於.NET

聚合方法

主要方法:

Count, LongCount: 返回輸入序列的元素數量, 並且滿足一個斷言(可選), SQL對應語法為COUNT()

Min, Max: 返回輸入序列中的最小或最大的元素, SQL對應語法為MIN(), MAX()

Sum, Average: 計算序列中的所有元素的總和或者平均數, SQL對應語法為SUM(), AVG()

Aggregate: 執行一個自定義的聚合計算, 無對應SQL語法

Count, LongCount

源序列: IEnumerable

斷言: TSource => bool (可選)

Count枚舉一個序列並返回其中的元素總數:

   1: int fullCount = new int[] { 5, 6, 7}.Count();    // 3

 

在IEnumerable.Count的內部實現中, 它首先測試輸入序列是否實現了ICollection, 如果是, 則直接調用ICollection.Count, 否則就利用一個簡單的計算數遍歷所有元素每次加1獲得最後的總數.

另外, 我們也可以在查詢中提供一個斷言:

   1: int digitCount = “jame921″.Count (c => char.IsDigit (c));   // 3

 

LongCount跟Count做一樣的工作, 只不過它返回的是一個64位的整數, 可以計算超過20億的元素

Min和Max

源序列: IEnumerable

可選結果選擇器: TSource => TResult

Min和Max分別返回輸入序列中最小和最大的元素:

   1: int[] numbers = { 28, 32, 14 };
   2:  
   3: int smallest = numbers.Min();    // 14;
   4:  
   5: int largest  = numbers.Max();    // 32;

 

你也可以包含一個選擇表達式:

   1: int smallest = numbers.Max (n => n % 10);   // 8;

 

如果元素本身並不是可比較的, 那麼選擇器表達式就是必須的了, 換句話說, 如果元素沒有實現IComparable, 例如:

   1: Purchase runtimeError =
   2:  
   3:   dataContext.Purchases.Min();      // 編譯錯誤
   4:  
   5: decimal? lowestPrice =
   6:  
   7:     dataContext.Purchases.Min (p => p.Price);    // OK

 

一個選擇器表達式不僅決定元素之間如何做比較, 同時也可以影響最後的結果. 例如前面的例子返回的結果是一個decimal類型的數值, 而不是一個purchase對象, 為了要獲得最便宜的采購訂單, 我們需要一個子查詢:

   1: Purchase cheapest = dataContext.Purchases
   2:  
   3:   .Where (p => p.Price ==
   4:  
   5:           dataContext.Purchases.Min(p2 => p2.Price))
   6:  
   7:     .FirstOrDefault();

 

Sum與Average

源序列: IEnumerable

可選的結果選擇器: TSource => TResult

Sum和Average這兩個聚合操作符使用與Min和Max類似:

   1: decimal[] numbers = { 3, 4, 8 };
   2:  
   3: decimal sumTotal  = numbers.Sum();       // 15
   4:  
   5:  average   = numbers.Average();   // 5

 

以下查詢返回names數組中每一個元素的長度總和:

   1: int combinedLength = names.Sum (s =>s.Length);

 

Sum和Average操作必需是關於數值類型(int, long, float, double以及nullable版本), 相反的, Min和Max就沒有這麼嚴格的限定, 它們可以操作那些實現了Icomparable的元素, 例如string. 此外, Average總是返回decimal或者double兩者之一:

1.如果選擇器類型是decimal,則返回類型也是decimal

2.如果選擇器類型是int, long, float, double, 則返回類型是double

這意味著下面的查詢無法編譯(因為double不能為自動轉換為int)

   1: int avg = new int[] { 3, 4 }.Average();

 

但是以下的查詢則沒有問題:

   1: double avg = new int[] { 3, 4}.Average();   // 3.5

 

Average隱式提高輸入值的精度以避免原有精度丟失. 這這個例子中, 我們取得平均值3.5, 而不需要去訴求於一個輸入元素的轉換:

   1: double avg = numbers.Average (n =>(double) n);

 

在LINQ to SQL中, Sum和Average被翻譯成了標准的SQL聚合函數, 以下的查詢返回了那些包含有訂單平均值 > 500的客戶名稱:

   1: from c in dataContext.Customers
   2:  
   3: where c.Purchases.Average (p => p.Price) > 500
   4:  
   5: select c.Name;

 

聚合

Aggregate允許你嵌入一個自定義的算法來實現那些不是很常用的聚合場景. Aggregations在LINQ to SQL當中不受支持. 以下的查詢演示了如果使用Aggregate來做與Sum的工作:

   1: int[] numbers = { 1, 2, 3 };
   2: int sum = numbers.Aggregate (0, (seed, n)=> seed + n);

 

  第一個參數是seed,表示從那個元素位置開始計算. 第二個參數是一個更新計算結果值的表達式, 並作為一個新的元素繼續循環下去. 我們還可以使用可選的第三個參數在返回值的時候再作進一步的project. 待續!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved