C#3.0新增功能09 LINQ 基礎04 基本 LINQ 查詢操作
- 2019 年 10 月 4 日
- 筆記
本篇介紹 LINQ 查詢表達式和一些在查詢中執行的典型操作。
獲取數據源
在 LINQ 查詢中,第一步是指定數據源。 和大多數程式語言相同,在使用 C# 時也必須先聲明變數,然後才能使用它。 在 LINQ 查詢中,先使用 from 子句引入數據源 (customers) 和範圍變數 (cust) 。
// 從 IEnumerable<Customer> 中查詢所有的客戶資訊 var queryAllCustomers = from cust in customers select cust;
範圍變數就像 foreach 循環中的迭代變數,但查詢表達式中不會真正發生迭代。 當執行查詢時,範圍變數將充當對 customers 中每個連續的元素的引用。 由於編譯器可以推斷 cust的類型,因此無需顯式指定它。 可通過 let 子句引入其他範圍變數。 有關詳細資訊,請參閱 let 子句。
對於非泛型數據源(例如 ArrayList),必須顯式鍵入範圍變數。 有關詳細資訊,請參閱如何:使用 LINQ 查詢 ArrayList (C#) 和 from 子句。
篩選
或許,最常見的查詢操作是以布爾表達式的形式應用篩選器。 篩選器使查詢僅返回表達式為 true 的元素。 將通過使用 where 子句生成結果。 篩選器實際指定要從源序列排除哪些元素。 在下列示例中,僅返回地址位於「London」的 customers。
var queryLondonCustomers = from cust in customers where cust.City == "London" select cust;
可使用熟悉的 C# 邏輯 AND 和 OR 運算符,在 where 子句中根據需要應用儘可能多的篩選器表達式。 例如,若要僅返回來自「London」的客戶 AND 該客戶名稱為「Devon」,可編寫以下程式碼:
where cust.City=="London" && cust.Name == "Devon"
要返回來自 London 或 Paris 的客戶,可編寫以下程式碼:
where cust.City == "London" || cust.City == "Paris"
中間件排序
對返回的數據進行排序通常很方便。 orderby 子句根據要排序類型的默認比較器,對返回序列中的元素排序。 例如,基於 Name 屬性,可將下列查詢擴展為對結果排序。 由於 Name是字元串,默認比較器將按字母順序從 A 到 Z 進行排序。
var queryLondonCustomers3 = from cust in customers where cust.City == "London" orderby cust.Name ascending select cust;
要對結果進行從 Z 到 A 的逆序排序,請使用 orderby…descending 子句。有關詳細資訊,請參閱 orderby 子句。
分組
group 子句用於對根據您指定的鍵所獲得的結果進行分組。 例如,可指定按 City 對結果進行分組,使來自 London 或 Paris 的所有客戶位於單獨的組內。 在這種情況下,cust.City是鍵。
// queryCustomersByCity 是 IEnumerable<IGrouping<string, Customer>> 類型 var queryCustomersByCity = from cust in customers group cust by cust.City; // customerGroup 是 IGrouping<string, Customer> 類型 foreach (var customerGroup in queryCustomersByCity) { Console.WriteLine(customerGroup.Key); foreach (Customer customer in customerGroup) { Console.WriteLine(" {0}", customer.Name); } }
使用 group 子句結束查詢時,結果將以列表的形式列出。 列表中的每個元素都是具有 Key成員的對象,列表中的元素根據該鍵被分組。
在循環訪問生成組序列的查詢時,必須使用嵌套 foreach 循環。 外層循環循環訪問每個組,內層循環循環訪問每個組的成員。
如果必須引用某個組操作的結果,可使用 into 關鍵字創建能被進一步查詢的標識符。 下列查詢僅返回包含兩個以上客戶的組:
// custQuery 是 IEnumerable<IGrouping<string, Customer>> 類型 var custQuery = from cust in customers group cust by cust.City into custGroup where custGroup.Count() > 2 orderby custGroup.Key select custGroup;
有關詳細資訊,請參閱 group 子句。
聯接
聯接操作在不同序列間創建關聯,這些序列在數據源中未被顯式模組化。 例如,可通過執行聯接來查找所有位置相同的客戶和分銷商。 在 LINQ 中,join 子句始終作用於對象集合,而非直接作用於資料庫表。
var innerJoinQuery = from cust in customers join dist in distributors on cust.City equals dist.City select new { CustomerName = cust.Name, DistributorName = dist.Name };
在 LINQ 中,不必像在 SQL 中那樣頻繁使用 join,因為 LINQ 中的外鍵在對象模型中表示為包含項集合的屬性。 例如 Customer 對象包含 Order 對象的集合。 不必執行聯接,只需使用點表示法訪問訂單:
from order in Customer.Orders...
有關詳細資訊,請參閱 join 子句。
選擇(投影)
select 子句生成查詢結果並指定每個返回的元素的「形狀」或類型。 例如,可以指定結果包含的是整個 Customer 對象、僅一個成員、成員的子集,還是某個基於計算或新對象創建的完全不同的結果類型。 當 select 子句生成除源元素副本以外的內容時,該操作稱為投影 。 使用投影轉換數據是 LINQ 查詢表達式的一種強大功能。 有關詳細資訊,請參閱使用 LINQ (C#) 和 select 子句進行數據轉換。
