本篇主要介紹標準查詢運算符的經常使用運算功能。html
排序操做基於一個或多個屬性對序列的元素進行排序。 第一個排序條件對元素執行主要排序。 經過指定第二個排序條件,您能夠對每一個主要排序組內的元素進行排序。sql
下圖展現了對一系列字符執行按字母順序排序操做的結果。數據庫
下節列出了對數據進行排序的標準查詢運算符方法。express
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
OrderBy | 按升序對值排序。 | orderby |
Enumerable.OrderBy Queryable.OrderBy |
OrderByDescending | 按降序對值排序。 | orderby … descending |
Enumerable.OrderByDescending Queryable.OrderByDescending |
ThenBy | 按升序執行次要排序。 | orderby …, … |
Enumerable.ThenBy Queryable.ThenBy |
ThenByDescending | 按降序執行次要排序。 | orderby …, … descending |
Enumerable.ThenByDescending Queryable.ThenByDescending |
Reverse | 反轉集合中元素的順序。 | 不適用。 | Enumerable.Reverse Queryable.Reverse |
下面的示例演示如何在 LINQ 查詢中使用 orderby
子句按字符串長度對數組中的字符串進行升序排序。編程
string[] words = { "the", "quick", "brown", "fox", "jumps" }; IEnumerable<string> query = from word in words orderby word.Length select word; foreach (string str in query) Console.WriteLine(str); /* 輸出: the fox quick brown jumps */
下面的示例演示如何在 LINQ 查詢中使用 orderby descending
子句按字符串的第一個字母對字符串進行降序排序。api
string[] words = { "the", "quick", "brown", "fox", "jumps" }; IEnumerable<string> query = from word in words orderby word.Substring(0, 1) descending select word; foreach (string str in query) Console.WriteLine(str); /* 輸出: the quick jumps fox brown */
下面的示例演示如何在 LINQ 查詢中使用 orderby
子句對數組中的字符串執行主要和次要排序。 首先按字符串長度,其次按字符串的第一個字母,對字符串進行升序排序。數組
string[] words = { "the", "quick", "brown", "fox", "jumps" }; IEnumerable<string> query = from word in words orderby word.Length, word.Substring(0, 1) select word; foreach (string str in query) Console.WriteLine(str); /* 輸出: fox the brown jumps quick */
下面的示例演示如何在 LINQ 查詢中使用 orderby descending
子句按升序執行主要排序,按降序執行次要排序。 首先按字符串長度,其次按字符串的第一個字母,對字符串進行排序。app
string[] words = { "the", "quick", "brown", "fox", "jumps" }; IEnumerable<string> query = from word in words orderby word.Length, word.Substring(0, 1) descending select word; foreach (string str in query) Console.WriteLine(str); /* 輸出: the fox quick jumps brown */
LINQ 中的集運算是指根據相同或不一樣集合(或集)中是否存在等效元素來生成結果集的查詢運算。框架
下節列出了執行集運算的標準查詢運算符方法。ide
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
Distinct | 刪除集合中的重複值。 | 不適用。 | Enumerable.Distinct Queryable.Distinct |
Except | 返回差集,差集指位於一個集合但不位於另外一個集合的元素。 | 不適用。 | Enumerable.Except Queryable.Except |
相交 | 返回交集,交集指同時出如今兩個集合中的元素。 | 不適用。 | Enumerable.Intersect Queryable.Intersect |
聯合 | 返回並集,並集指位於兩個集合中任一集合的惟一的元素。 | 不適用。 | Enumerable.Union Queryable.Union |
下圖演示字符序列上 Enumerable.Distinct 方法的行爲。 返回的序列包含輸入序列的惟一元素。
下圖演示 Enumerable.Except 的行爲。 返回的序列只包含位於第一個輸入序列但不位於第二個輸入序列的元素。
下圖演示 Enumerable.Intersect 的行爲。 返回的序列包含兩個輸入序列共有的元素。
下圖演示對兩個字符序列執行的聯合操做。 返回的序列包含兩個輸入序列的惟一元素。
篩選是指將結果集限制爲僅包含知足指定條件的元素的操做。 它也稱爲選定內容。
下圖演示了對字符序列進行篩選的結果。 篩選操做的謂詞指定字符必須爲「A」。
下面一節列出了執行所選內容的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
OfType | 根據其轉換爲特定類型的能力選擇值。 | 不適用。 | Enumerable.OfType Queryable.OfType |
Where | 選擇基於謂詞函數的值。 | where |
Enumerable.Where Queryable.Where |
如下示例使用 where
子句從數組中篩選具備特定長度的字符串。
string[] words = { "the", "quick", "brown", "fox", "jumps" }; IEnumerable<string> query = from word in words where word.Length == 3 select word; foreach (string str in query) Console.WriteLine(str); /* 輸出: the fox */
限定符運算返回一個 Boolean 值,該值指示序列中是否有一些元素知足條件或是否全部元素都知足條件。
下圖描述了兩個不一樣源序列上的兩個不一樣限定符運算。 第一個運算詢問是否有一個或多個元素爲字符「A」,結果爲 true
。 第二個運算詢問是否全部元素都爲字符「A」,結果爲 true
。
下節列出了執行限定符運算的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
所有 | 肯定是否序列中的全部元素都知足條件。 | 不適用。 | Enumerable.All Queryable.All |
任意 | 肯定序列中是否有元素知足條件。 | 不適用。 | Enumerable.Any Queryable.Any |
包含 | 肯定序列是否包含指定的元素。 | 不適用。 | Enumerable.Contains Queryable.Contains |
投影是指將對象轉換爲一種新形式的操做,該形式一般只包含那些將隨後使用的屬性。 經過使用投影,您能夠構造從每一個對象生成的新類型。 能夠投影屬性,並對該屬性執行數學函數。 還能夠在不更改原始對象的狀況下投影該對象。
下面一節列出了執行投影的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
選擇 | 投影基於轉換函數的值。 | select |
Enumerable.Select Queryable.Select |
SelectMany | 投影基於轉換函數的值序列,而後將它們展平爲一個序列。 | 使用多個 from 子句 |
Enumerable.SelectMany Queryable.SelectMany |
下面的示例使用 select
子句來投影字符串列表中每一個字符串的第一個字母。
List<string> words = new List<string>() { "an", "apple", "a", "day" }; var query = from word in words select word.Substring(0, 1); foreach (string s in query) Console.WriteLine(s); /* 輸出: a a a d */
下面的示例使用多個 from
子句來投影字符串列表中每一個字符串中的每一個單詞。
List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" }; var query = from phrase in phrases from word in phrase.Split(' ') select word; foreach (string s in query) Console.WriteLine(s); /* 輸出: an apple a day the quick brown fox */
Select()
和 SelectMany()
的工做都是依據源值生成一個或多個結果值。 Select()
爲每一個源值生成一個結果值。 所以,整體結果是一個與源集合具備相同元素數目的集合。 與之相反,SelectMany()
生成單個整體結果,其中包含來自每一個源值的串聯子集合。 做爲參數傳遞到 SelectMany()
的轉換函數必須爲每一個源值返回一個可枚舉值序列。 而後,SelectMany()
串聯這些可枚舉序列,以建立一個大的序列。
下面兩個插圖演示了這兩個方法的操做之間的概念性區別。 在每種狀況下,假定選擇器(轉換)函數從每一個源值中選擇一個由花卉數據組成的數組。
下圖描述 Select()
如何返回一個與源集合具備相同元素數目的集合。
下圖描述 SelectMany()
如何將中間數組序列串聯爲一個最終結果值,其中包含每一箇中間數組中的每一個值。
下面的示例比較 Select()
和 SelectMany()
的行爲。 代碼經過從源集合的每一個花卉名稱列表中提取前兩項來建立一個「花束」。 此示例中,transform 函數 Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) 使用的「單值」自己便是值的集合。 這須要額外的 foreach
循環,以便枚舉每一個子序列中的每一個字符串。
1 class Bouquet 2 { 3 public List<string> Flowers { get; set; } 4 } 5 6 static void SelectVsSelectMany() 7 { 8 List<Bouquet> bouquets = new List<Bouquet>() { 9 new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }}, 10 new Bouquet { Flowers = new List<string> { "tulip", "rose", "orchid" }}, 11 new Bouquet { Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }}, 12 new Bouquet { Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }} 13 }; 14 15 // *********** Select *********** 16 IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers); 17 18 // ********* SelectMany ********* 19 IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers); 20 21 Console.WriteLine("Results by using Select():"); 22 // 注意這裏額外的foreach循環 23 foreach (IEnumerable<String> collection in query1) 24 foreach (string item in collection) 25 Console.WriteLine(item); 26 27 Console.WriteLine("\nResults by using SelectMany():"); 28 foreach (string item in query2) 29 Console.WriteLine(item); 30 31 /* 輸出: 32 33 Results by using Select(): 34 sunflower 35 daisy 36 daffodil 37 larkspur 38 tulip 39 rose 40 orchid 41 gladiolis 42 lily 43 snapdragon 44 aster 45 protea 46 larkspur 47 lilac 48 iris 49 dahlia 50 51 Results by using SelectMany(): 52 sunflower 53 daisy 54 daffodil 55 larkspur 56 tulip 57 rose 58 orchid 59 gladiolis 60 lily 61 snapdragon 62 aster 63 protea 64 larkspur 65 lilac 66 iris 67 dahlia 68 */ 69 70 }
LINQ 中的分區是指將輸入序列劃分爲兩個部分的操做,無需從新排列元素,而後返回其中一個部分。
下圖顯示對字符序列進行三種不一樣的分區操做的結果。 第一個操做返回序列中的前三個元素。 第二個操做跳過前三個元素,返回剩餘元素。 第三個操做跳過序列中的前兩個元素,返回接下來的三個元素。
下面一節列出了對序列進行分區的標準查詢運算符方法。
運算符名稱 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
Skip | 跳過序列中指定位置以前的元素。 | 不適用。 | Enumerable.Skip Queryable.Skip |
SkipWhile | 基於謂詞函數跳過元素,直到元素不符合條件。 | 不適用。 | Enumerable.SkipWhile Queryable.SkipWhile |
Take | 獲取序列中指定位置以前的元素。 | 不適用。 | Enumerable.Take Queryable.Take |
TakeWhile | 基於謂詞函數獲取元素,直到元素不符合條件。 | 不適用。 | Enumerable.TakeWhile Queryable.TakeWhile |
聯接兩個數據源就是將一個數據源中的對象與另外一個數據源中具備相同公共屬性的對象相關聯。
當查詢所面向的數據源相互之間具備沒法直接領會的關係時,聯接就成爲一項重要的運算。在面向對象的編程中,這可能意味着在未建模對象之間進行關聯,例如對單向關係進行反向推理。 下面是單向關係的一個示例:Customer 類有一個類型爲 City 的屬性,但 City 類沒有做爲 Customer 對象集合的屬性。 若是你具備一個 City 對象列表,而且要查找每一個城市中的全部客戶,則可使用聯接運算完成此項查找。
LINQ 框架中提供的 join 方法包括 Join 和 GroupJoin。 這些方法執行同等聯接,即根據 2 個數據源的鍵是否相等來匹配這 2 個數據源的聯接。 (與此相較,Transact-SQL 支持除「等於」以外的聯接運算符,例如「小於」運算符。)用關係數據庫術語表達,就是說 Join 實現了內部聯接,這種聯接只返回那些在另外一個數據集中具備匹配項的對象。 GroupJoin 方法在關係數據庫術語中沒有直接等效項,但實現了內部聯接和左外部聯接的超集。 左外部聯接是指返回第一個(左側)數據源的每一個元素的聯接,即便其餘數據源中沒有關聯元素。
下圖顯示了一個概念性視圖,其中包含兩個集合以及這兩個集合中的包含在內部聯接或左外部聯接中的元素。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
聯接 | 根據鍵選擇器函數聯接兩個序列並提取值對。 | join … in … on … equals … |
Enumerable.Join Queryable.Join |
GroupJoin | 根據鍵選擇器函數聯接兩個序列,並對每一個元素的結果匹配項進行分組。 | join … in … on … equals … into … |
Enumerable.GroupJoin Queryable.GroupJoin |
分組是指將數據分到不一樣的組,使每組中的元素擁有公共的屬性。
下圖演示了對字符序列進行分組的結果。 每一個組的鍵是字符。
下一節列出了對數據元素進行分組的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
GroupBy | 對共享通用屬性的元素進行分組。 每組由一個 IGrouping<TKey,TElement> 對象表示。 | group … by 或 group … by … into … |
Enumerable.GroupBy Queryable.GroupBy |
ToLookup | 將元素插入基於鍵選擇器函數的 Lookup<TKey,TElement>(一種一對多字典)。 | 不適用。 | Enumerable.ToLookup |
下列代碼示例根據奇偶性,使用 group by
子句對列表中的整數進行分組。
List<int> numbers = new List<int>() { 35, 44, 200, 84, 3987, 4, 199, 329, 446, 208 }; IEnumerable<IGrouping<int, int>> query = from number in numbers group number by number % 2; foreach (var group in query) { Console.WriteLine(group.Key == 0 ? "\nEven numbers:" : "\nOdd numbers:"); foreach (int i in group) Console.WriteLine(i); } /* 輸出: Odd numbers: 35 3987 199 329 Even numbers: 44 200 84 4 446 208 */
生成是指建立新的值序列。
下面一節列出了執行生成的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
DefaultIfEmpty | 用默認值單一實例集合替換空集合。 | 不適用。 | Enumerable.DefaultIfEmpty Queryable.DefaultIfEmpty |
空 | 返回一個空集合。 | 不適用。 | Enumerable.Empty |
範圍 | 生成包含數字序列的集合。 | 不適用。 | Enumerable.Range |
Repeat | 生成包含一個重複值的集合。 | 不適用。 | Enumerable.Repeat |
兩個序列,其相應元素相等且具備被視爲相等的相同數量的元素。
方法名 | 說明 | C# 查詢表達式語法 | 更多信息 |
---|---|---|---|
SequenceEqual | 經過以成對方式比較元素肯定兩個序列是否相等。 | 不適用。 | Enumerable.SequenceEqual Queryable.SequenceEqual |
元素運算從序列中返回惟1、特定的元素。
下節列出了執行元素運算的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
ElementAt | 返回集合中指定索引處的元素。 | 不適用。 | Enumerable.ElementAt Queryable.ElementAt |
ElementAtOrDefault | 返回集合中指定索引處的元素;若是索引超出範圍,則返回默認值。 | 不適用。 | Enumerable.ElementAtOrDefault Queryable.ElementAtOrDefault |
First | 返回集合的第一個元素或知足條件的第一個元素。 | 不適用。 | Enumerable.First Queryable.First |
FirstOrDefault | 返回集合的第一個元素或知足條件的第一個元素。 若是此類元素不存在,則返回默認值。 | 不適用。 | Enumerable.FirstOrDefault Queryable.FirstOrDefault Queryable.FirstOrDefault<TSource>(IQueryable<TSource>) |
上一個 | 返回集合的最後一個元素或知足條件的最後一個元素。 | 不適用。 | Enumerable.Last Queryable.Last |
LastOrDefault | 返回集合的最後一個元素或知足條件的最後一個元素。若是此類元素不存在,則返回默認值。 | 不適用。 | Enumerable.LastOrDefault Queryable.LastOrDefault |
Single | 返回集合的惟一一個元素或知足條件的惟一一個元素。若是沒有要返回的元素或要返回多個元素,則引起 InvalidOperationException。 | 不適用。 | Enumerable.Single Queryable.Single |
SingleOrDefault | 返回集合的惟一一個元素或知足條件的惟一一個元素。若是沒有要返回的元素,則返回默認值。 若是要返回多個元素,則引起 InvalidOperationException。 | 不適用。 | Enumerable.SingleOrDefault Queryable.SingleOrDefault |
轉換方法可更改輸入對象的類型。
LINQ 查詢中的轉換運算可用於各類應用程序。 如下是一些示例:
Enumerable.AsEnumerable 方法可用於隱藏類型的標準查詢運算符自定義實現。
Enumerable.OfType 方法可用於爲 LINQ 查詢啓用非參數化集合。
Enumerable.ToArray、Enumerable.ToDictionary、Enumerable.ToList 和 Enumerable.ToLookup方法可用於強制執行即時的查詢,而不是將其推遲到枚舉該查詢時。
下表列出了執行數據類型轉換的標準查詢運算符方法。
本表中名稱以「As」開頭的轉換方法可更改源集合的靜態類型,但不對其進行枚舉。 名稱以「To」開頭的方法可枚舉源集合,並將項放入相應的集合類型。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
AsEnumerable | 返回類型化爲 IEnumerable<T> 的輸入。 | 不適用。 | Enumerable.AsEnumerable |
AsQueryable | 將(泛型)IEnumerable 轉換爲(泛型)IQueryable。 | 不適用。 | Queryable.AsQueryable |
Cast | 將集合中的元素轉換爲指定類型。 | 使用顯式類型化的範圍變量。 例如:from string str in words |
Enumerable.Cast Queryable.Cast |
OfType | 根據其轉換爲指定類型的能力篩選值。 | 不適用。 | Enumerable.OfType Queryable.OfType |
ToArray | 將集合轉換爲數組。 此方法強制執行查詢。 | 不適用。 | Enumerable.ToArray |
ToDictionary | 根據鍵選擇器函數將元素放入 Dictionary<TKey,TValue>。 此方法強制執行查詢。 | 不適用。 | Enumerable.ToDictionary |
ToList | 將集合轉換爲 List<T>。 此方法強制執行查詢。 | 不適用。 | Enumerable.ToList |
ToLookup | 根據鍵選擇器函數將元素放入 Lookup<TKey,TElement>(一對多字典)。 此方法強制執行查詢。 | 不適用。 | Enumerable.ToLookup |
下面的代碼示例使用顯式類型化的範圍變量將類型轉換爲子類型,而後才訪問僅在此子類型上可用的成員。
1 class Plant 2 { 3 public string Name { get; set; } 4 } 5 6 class CarnivorousPlant : Plant 7 { 8 public string TrapType { get; set; } 9 } 10 11 static void Cast() 12 { 13 Plant[] plants = new Plant[] { 14 new CarnivorousPlant { Name = "Venus Fly Trap", TrapType = "Snap Trap" }, 15 new CarnivorousPlant { Name = "Pitcher Plant", TrapType = "Pitfall Trap" }, 16 new CarnivorousPlant { Name = "Sundew", TrapType = "Flypaper Trap" }, 17 new CarnivorousPlant { Name = "Waterwheel Plant", TrapType = "Snap Trap" } 18 }; 19 20 var query = from CarnivorousPlant cPlant in plants 21 where cPlant.TrapType == "Snap Trap" 22 select cPlant; 23 24 foreach (Plant plant in query) 25 Console.WriteLine(plant.Name); 26 27 /* 輸出: 28 29 Venus Fly Trap 30 Waterwheel Plant 31 */ 32 }
串聯是指將一個序列附加到另外一個序列的操做。
下圖描繪了兩個字符序列的串聯操做。
下面一節列出了執行串聯的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
Concat | 鏈接兩個序列以組成一個序列。 | 不適用。 | Enumerable.Concat Queryable.Concat |
聚合運算從值的集合中計算出單個值。 例如,從一個月累計的每日溫度值計算出日平均溫度值就是一個聚合運算。
下圖顯示對數字序列進行兩種不一樣聚合操做所得結果。 第一個操做累加數字。 第二個操做返回序列中的最大值。
下節列出了執行聚合運算的標準查詢運算符方法。
方法名 | 說明 | C# 查詢表達式語法 | 詳細信息 |
---|---|---|---|
聚合 | 對集合的值執行自定義聚合運算。 | 不適用。 | Enumerable.Aggregate Queryable.Aggregate |
平均值 | 計算值集合的平均值。 | 不適用。 | Enumerable.Average Queryable.Average |
計數 | 對集合中元素計數,可選擇僅對知足謂詞函數的元素計數。 | 不適用。 | Enumerable.Count Queryable.Count |
LongCount | 對大型集合中元素計數,可選擇僅對知足謂詞函數的元素計數。 | 不適用。 | Enumerable.LongCount Queryable.LongCount |
最大值 | 肯定集合中的最大值。 | 不適用。 | Enumerable.Max Queryable.Max |
最小值 | 肯定集合中的最小值。 | 不適用。 | Enumerable.Min Queryable.Min |
Sum | 對集合中的值求和。 | 不適用。 | Enumerable.Sum Queryable.Sum |