本專題概要:
引言:
終於到了C# 3中最重要特性的介紹了,可以說之前所有介紹的特性都是為了Linq而做准備的,然而要想深入理解Linq並不是這個專題可以介紹完的,所以我打算這個專題將對Linq做一個簡單的介紹,對於Linq的深入理解我將會後面單獨作為一個系列要和大家分享下。
一、Linq是什麼?
Linq也就是Language Integrated Query的縮寫,即語言集成查詢,是微軟在.Net 3.5中提出的一項新技術, Linq主要包含4個組件——Linq to Objects、Linq to XML、Linq to DataSet 和Linq to SQL。在這裡不會具體介紹這4個組件的內容,只會給出一個大致的介紹, 下面先看看Linq的一個架構圖,希望可以讓大家可以對Linq有一個全面的認識:
下面簡單介紹下四個組件:
二、使用Linq的好處在哪裡
第一部分中說到Linq中包括四個組件,分別是對不同數據進行增刪改查的一些操作,然而以前也是有相關技術來對這些數據進行操作,(例如,對數據庫的操作,之前有Ado.Net 對其進行支持,對XML的操作,之前也可以XPath來操作XML文件等), 此時應該大家都會有個疑問的——為什麼以前都有相關的技術對其進行支持,那我們為什麼還需要Linq呢?對於這個疑問答案很簡單,Linq 使操作這些數據源更加簡單,方便和易於理解,之前的技術操作起來過於繁瑣,所以微軟也有上進心啊,希望可以做的更好啊,所以就在C# 3中提出了Linq來方便大家操作這些數據源,下面通過對比來說明Linq是如何簡單方便:
2.1 查詢集合中的數據
之前我們查詢集合中的數據一般會使用for或foreach語句來進行查詢,而Linq 使用查詢表達式來進行查詢,Linq 表達式比之前用for或forach的方式更加簡潔,比較容易添加篩選條件,下面就具體看看兩者方式的比較代碼(我們這裡假設一個場景——返回集合中序號為偶數的元素)
使用foreach 語句來返回序號為偶數的元素的實現代碼如下:
static void Main(string[] args) { #region Linq to objects 對比 Console.WriteLine(使用老方法來對集合對象查詢,查詢結果為:); OldQuery(); Console.WriteLine(使用Linq方法來對集合對象查詢,查詢結果為:); LinqQuery(); Console.Read(); #endregion } #region Linq to Objects對比 // 使用Linq 和使用Foreach語句的對比 // 1. 使用foreach返回集合中序號為偶數的元素 private static void OldQuery() { // 初始化查詢的數據 Listcollection = new List (); for (int i = 0; i < 10; i++) { collection.Add(A+i.ToString()); } // 創建保存查詢結果的集合 List queryResults = new List (); foreach (string s in collection) { // 獲取元素序號 int index = int.Parse(s.Substring(1)); // 查詢序號為偶數的元素 if (index % 2 == 0) { queryResults.Add(s); } } // 輸出查詢結果 foreach (string s in queryResults) { Console.WriteLine(s); } } // 2. 使用Linq返回集合中序號為偶數的元素 private static void LinqQuery() { // 初始化查詢的數據 List collection = new List (); for (int i = 0; i < 10; i++) { collection.Add(A + i.ToString()); } // 創建查詢表達式來獲得序號為偶數的元素 var queryResults = from s in collection let index = int.Parse(s.Substring(1)) where index % 2 == 0 select s; // 輸出查詢結果 foreach (string s in queryResults) { Console.WriteLine(s); } } #endregion
從上面的兩個方法比較中可以看出使用Linq對集合進行查詢時確實簡單了許多,並且也容易添加篩選條件(只需要在Where 後面添加額外的篩選條件即可),運行結果當然也是我們期望的,下面也附上下運行結果截圖:
2.2 查詢XML文件
之前我們大部分都會使用XPath來對XML文件進行查詢,然而使用XPath來查詢XML文件需要首先知道XML文件的具體結構,而Linq 查詢表達式在查詢XML數據的時,可以不需要知道XML文件結構,並且編碼更加簡單,容易添加判斷的條件,下面就具體代碼來說明使用Linq查詢的好處(這裡假設一個場景——有一個定義Persons的XML文件,現在我們要求查找出XML文件中Name節點為“李四”的元素):
static void Main(string[] args) { #region Linq to XML 對比 Console.WriteLine(使用XPath來對XML文件查詢,查詢結果為:); OldLinqToXMLQuery(); Console.WriteLine(使用Linq方法來對XML文件查詢,查詢結果為:); UsingLinqLinqtoXMLQuery(); Console.ReadKey(); #endregion } #region Linq to XML 對比 // 初始化XML數據 private static string xmlString =+ ; // 使用XPath方式來對XML文件進行查詢 private static void OldLinqToXMLQuery() { // 導入XML文件 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); // 創建查詢XML文件的XPath string xPath = /Persons/Person; // 查詢Person元素 XmlNodeList querynodes = xmlDoc.SelectNodes(xPath); foreach (XmlNode node in querynodes) { // 查詢名字為李四的元素 foreach (XmlNode childnode in node.ChildNodes) { if (childnode.InnerXml == 李四) { Console.WriteLine(姓名為: +childnode.InnerXml + Id 為: + node.Attributes[Id].Value); } } } } // 使用Linq 來對XML文件進行查詢 private static void UsingLinqLinqtoXMLQuery() { // 導入XML XElement xmlDoc = XElement.Parse(xmlString); // 創建查詢,獲取姓名為“李四”的元素 var queryResults = from element in xmlDoc.Elements(Person) where element.Element(Name).Value == 李四 select element; // 輸出查詢結果 foreach (var xele in queryResults) { Console.WriteLine(姓名為: + xele.Element(Name).Value + Id 為: + xele.Attribute(Id).Value); } } #endregion+ +張三 + 18++ +李四 + 19++ +王五 + 22 +
使用XPath方式來查詢XML文件時,首先需要知道XML文件的具體結構(代碼中需要指定XPath為/Persons/Person, 這就說明必須知道XML的組成結構了),然而使用Linq方式卻不需要知道XML文檔結構,並且從代碼書寫的量上也可以看出使用Linq方式的簡潔性,下面附上運行結果截圖:
對於Linq to SQL 和Linq to DataSet的例子,我這裡就不一一給出了,從上面的兩個例子已經完全可以說明使用Linq的好處了,下面總結我理解的好處有:
三、Linq的實際操作例子——使用Linq遍歷文件目錄
通過前面兩部分大家大致可以知道Linq的強大了吧,這部分就具體給出一個例子來看看使用Linq具體可以做些什麼事情的? 如果大家做一個文件管理系統的時候,大家都需要遍歷文件目錄的吧,下面就使用Linq來查找在文件目錄中的是否存在特定的文件,具體代碼如下:
static void Main(string[] args) { string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); //FileQuery2(desktop); if (!string.IsNullOrEmpty(FileQuery())) { Console.WriteLine(FileQuery()); } else { Console.WriteLine(電腦桌面上不存在text.txt文件); } Console.Read(); } // 使用Linq查詢 // 查詢桌面是否存在text.txt文件 private static string FileQuery() { string desktopdir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); // 獲得指定目錄和子目錄中的文件名 string[] filenames = Directory.GetFiles(desktopdir, *.*, SearchOption.AllDirectories); Listfiles = new List (); foreach (var filename in filenames) { files.Add(new FileInfo(filename)); } var results = from file in files where file.Name == text.txt select file; // 輸出查詢結果 StringBuilder queryResult = new StringBuilder(); foreach (var result in results) { queryResult.AppendLine(文件的路徑為: + result.FullName); } return queryResult.ToString(); } /// /// 使用遞歸來查找文件 /// 查詢桌面是否存在text.txt文件 /// private static void FileQuery2(string path) { // 獲得指定目錄中的文件(包含子目錄) string[] filenames = Directory.GetFiles(path); Listfiles = new List (); foreach (var filename in filenames) { files.Add(new FileInfo(filename)); } var results = from file in files where file.Name == text.txt select file; // 輸出查詢結果 StringBuilder queryResult = new StringBuilder(); foreach (var result in results) { Console.WriteLine(文件的路徑為: + result.FullName); } // 獲得所有子目錄 string[] dirs = Directory.GetDirectories(path); if (dirs.Length > 0) { foreach (string dir in dirs) { FileQuery2(dir); } } }
運行結果為:
我的電腦桌面文件結果為:
Desttop文件夾 text.txt mytext文件夾 text文件夾 text.txt text.txt
四、小結
到這裡本專題的內容就介紹完了, 本專題主要和大家簡單分享了下我對Linq的認識,希望讓大家對Linq有個大概的認識,在後面的深入理解Linq系列中將會和大家一起剖析下Linq的實現原理。並且這個專題也是C# 3特性中的最後一個特性的介紹了,在後面一個專題中將帶來C# 4中一個最重要的特性——動態類型(dynamic )的引入