查詢 是一種從數據源檢索數據的表達式。 查詢一般用專門的查詢語言來表示。 隨着時間的推移,人們已經爲各類數據源開發了不一樣的語言;例如,用於關係數據庫的 SQL 和用於 XML 的 XQuery。 所以,開發人員對於他們必須支持的每種數據源或數據格式,都不得不學習一種新的查詢語言。 LINQ 經過提供一種跨各類數據源和數據格式使用數據的一致模型,簡化了這一狀況。 在 LINQ 查詢中,始終會用到對象。 可使用相同的基本編碼模式來查詢和轉換 XML 文檔、SQL 數據庫、ADO.NET 數據集、.NET 集合中的數據以及 LINQ 提供程序可用的任何其餘格式的數據。html
全部 LINQ 查詢操做都由如下三個不一樣的操做組成:sql
獲取數據源。數據庫
建立查詢。express
執行查詢。api
下面的示例演示如何用源代碼表示查詢操做的三個部分。 爲方便起見,此示例將一個整數數組用做數據源;但其中涉及的概念一樣適用於其餘數據源。 本主題的其他部分也會引用此示例。數組
class IntroToLINQ { static void Main() { // 1. 數據源 int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 }; // 2. 查詢表達式 numQuery 是 IEnumerable<int> 類型 var numQuery = from num in numbers where (num % 2) == 0 select num; // 3. 執行查詢 foreach (int num in numQuery) { Console.Write("{0,1} ", num); } } }
下圖演示完整的查詢操做。 在 LINQ 中,查詢的執行與查詢自己大相徑庭;換句話說,若是隻是建立查詢變量,則不會檢索任何數據。緩存
上例中,數據源是一個數組,所以它隱式支持泛型 IEnumerable<T> 接口。 這一事實意味着該數據源能夠用 LINQ 進行查詢。 查詢在 foreach
語句中執行,且 foreach
須要 IEnumerable 或 IEnumerable<T>。 支持 IEnumerable<T> 或派生接口(如泛型 IQueryable<T>)的類型稱爲可查詢類型。ide
可查詢類型不須要進行修改或特殊處理就能夠用做 LINQ 數據源。 若是源數據尚未做爲可查詢類型出如今內存中,則 LINQ 提供程序必須以此方式表示源數據。 例如,LINQ to XML 將 XML 文檔加載到可查詢的 XElement 類型中:函數
// using System.Xml.Linq; XElement contacts = XElement.Load(@"c:\myContactList.xml");// 從 xml 文件建立數據源
藉助 LINQ to SQL,首先在 Visual Studio 中手動或使用 Visual Studio 中的 LINQ to SQL 工具在設計時建立對象關係映射。 針對這些對象編寫查詢,而後由 LINQ to SQL 在運行時處理與數據庫的通訊。 下例中,Customers
表示數據庫中的特定表,而查詢結果的類型 IQueryable<T> 派生自 IEnumerable<T>。工具
Northwnd db = new Northwnd(@"c:\northwnd.mdf"); // 查詢城市名稱爲 London 的客戶 IQueryable<Customer> custQuery = from cust in db.Customers where cust.City == "London" select cust;
有關如何建立特定類型的數據源的詳細信息,請參閱各類 LINQ 提供程序的文檔。 但基本規則很簡單:LINQ 數據源是支持泛型 IEnumerable<T> 接口或從中繼承的接口的任意對象。
支持非泛型 IEnumerable 接口的類型(如 ArrayList)還可用做 LINQ 數據源。 有關詳細信息,請參閱如何:使用 LINQ 查詢 ArrayList (C#)。
查詢指定要從數據源中檢索的信息。 查詢還能夠指定在返回這些信息以前如何對其進行排序、分組和結構化。 查詢存儲在查詢變量中,並用查詢表達式進行初始化。 爲使編寫查詢的工做變得更加容易,C# 引入了新的查詢語法。
上一個示例中的查詢從整數數組中返回全部偶數。 該查詢表達式包含三個子句:from
、where
和 select
。 (若是熟悉 SQL,會注意到這些子句的順序與 SQL 中的順序相反。)from
子句指定數據源,where
子句應用篩選器,select
子句指定返回的元素的類型。LINQ 查詢表達式一節中詳細討論了這些子句和其餘查詢子句。 目前須要注意的是,在 LINQ 中,查詢變量自己不執行任何操做而且不返回任何數據。 它只是存儲在之後某個時刻執行查詢時爲生成結果而必需的信息。 有關在後臺如何構造查詢的詳細信息,請參閱標準查詢運算符概述 (C#)。
還可使用方法語法來表示查詢。 有關詳細信息,請參閱 LINQ 中的查詢語法和方法語法。
如前所述,查詢變量自己只存儲查詢命令。 查詢的實際執行將推遲到在 foreach
語句中循環訪問查詢變量以後進行。 此概念稱爲延遲執行,下面的示例對此進行了演示:
// 執行查詢 foreach (int num in numQuery) { Console.Write("{0,1} ", num); }
foreach
語句也是檢索查詢結果的地方。 例如,在上一個查詢中,迭代變量 num
保存了返回的序列中的每一個值(一次保存一個值)。
因爲查詢變量自己從不保存查詢結果,所以能夠根據須要隨意執行查詢。 例如,能夠經過一個單獨的應用程序持續更新數據庫。 在應用程序中,能夠建立一個檢索最新數據的查詢,並能夠按某一時間間隔反覆執行該查詢以便每次檢索不一樣的結果。
對一系列源元素執行聚合函數的查詢必須首先循環訪問這些元素。 Count
、Max
、Average
和 First
就屬於此類查詢。 因爲查詢自己必須使用 foreach
以便返回結果,所以這些查詢在執行時不使用顯式 foreach
語句。 另外還要注意,這些類型的查詢返回單個值,而不是 IEnumerable
集合。 下面的查詢返回源數組中偶數的計數:
var evenNumQuery = from num in numbers where (num % 2) == 0 select num; int evenNumCount = evenNumQuery.Count();
要強制當即執行任何查詢並緩存其結果,可調用 ToList 或 ToArray 方法。
List<int> numQuery2 = (from num in numbers where (num % 2) == 0 select num).ToList(); var numQuery3 = (from num in numbers where (num % 2) == 0 select num).ToArray();
此外,還能夠經過在緊跟查詢表達式以後的位置放置一個 foreach
循環來強制執行查詢。 可是,經過調用 ToList
或 ToArray
,也能夠將全部數據緩存在單個集合對象中。
其餘技術請參考