[C# 基礎知識系列]專題十六:Linq介紹


本專題概要:

  • Linq是什么
  • 使用Linq的好處在哪里
  • Linq的實際操作例子——使用Linq遍歷文件目錄
  • 小結

 引言:

   終於到了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 to SQL 組件——可以查詢基於關系數據的數據(微軟本身只是實現了對SQL Server的查詢,可以對數據庫中的數據進行查詢,修改,插入,刪除,排序等操作
  • Linq to Dataset組件——可以查詢DasaSet對象中的數據,並對數據進行增刪改查的操作
  • Linq to Objects組件——可以查詢IEnumberable 或IEnumberable<T>集合
  • Linq to XML 組件——可以差選和操作XML文件,比Xpath操作XML更加方便

二、使用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()
        {
            // 初始化查詢的數據
            List<string> collection = new List<string>();
            for (int i = 0; i < 10; i++)
            {
                collection.Add("A"+i.ToString());
            }
          
            // 創建保存查詢結果的集合
            List<string> queryResults = new List<string>();
            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<string> collection = new List<string>();
            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 = 
            "<Persons>"+
            "<Person Id='1'>"+
            "<Name>張三</Name>"+
            "<Age>18</Age>"+
            "</Person>" +
            "<Person Id='2'>"+
            "<Name>李四</Name>"+
            "<Age>19</Age>"+
            "</Person>"+
             "<Person Id='3'>" +
            "<Name>王五</Name>" +
            "<Age>22</Age>" +
            "</Person>"+
            "</Persons>";

        // 使用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

使用XPath方式來查詢XML文件時,首先需要知道XML文件的具體結構(代碼中需要指定XPath為"/Persons/Person", 這就說明必須知道XML的組成結構了),然而使用Linq方式卻不需要知道XML文檔結構,並且從代碼書寫的量上也可以看出使用Linq方式的簡潔性,下面附上運行結果截圖:

對於Linq to SQL 和Linq to DataSet的例子,我這里就不一一給出了,從上面的兩個例子已經完全可以說明使用Linq的好處了,下面總結我理解的好處有:

  • Linq 查詢表達式使用上更加簡單,而且也易於理解(沒有接觸過Linq的人也可以大致猜出代碼的意圖是什么的)
  • Linq 提供了更多的功能,我們可以查詢、排序、分組、增加和刪除等操作數據的大部分功能
  • 可以使用Linq處理多種數據源,也可以為特定的數據源定義自己的Linq實現(這點將會在深入理解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);
            List<FileInfo> files = new List<FileInfo>();
            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();
        }

        /// <summary>
        /// 使用遞歸來查找文件
        ///  查詢桌面是否存在text.txt文件
        /// </summary>
        private static void FileQuery2(string path)
        {
            // 獲得指定目錄中的文件(包含子目錄)
            string[] filenames = Directory.GetFiles(path);
            List<FileInfo> files = new List<FileInfo>();
            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 )的引入

 專題中的源碼: http://files.cnblogs.com/zhili/LinqDemo.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM