LINQ之路 5:LINQ查詢運算式

來源:互聯網
上載者:User
文章目錄
  • 範圍變數
  • 查詢運算式和方法文法
  • 組合查詢文法

書寫LINQ查詢時又兩種文法可供選擇:方法文法(Fluent Syntax)和查詢運算式(Query Expression)。

LINQ方法文法的本質是通過擴充方法和Lambda運算式來建立查詢。C# 3.0對於LINQ運算式還引入了聲明式的查詢運算式,也叫查詢文法,通常來講,它是建立LINQ查詢的更加快捷的方式。儘管通過查詢文法寫出的查詢比較類似於SQL查詢,但實際上查詢運算式的產生並不是建立在SQL之上,而是建立在函數式程式設計語言如LISP和Haskell中的list comprehensions(列表解析)功能之上。本篇會對LINQ查詢文法進行詳細的介紹。

我們在前一篇LINAQ方法文法中所舉的樣本:擷取所有包含字母”a”的姓名,按長度排序並將結果轉為大寫。下面是與之等價的查詢運算式文法:

        static void Main(string[] args)
{
string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

IEnumerable<string> query =
from n in names
where n.Contains("a") // Filter elements
orderby n n.Length // Sort elements, (orderby n 改為 orderby n.Length, 感謝網友搏擊的小船發現該處錯誤)
select n.ToUpper(); // Translate each element

foreach (string name in query)
Console.WriteLine(name);
}

查詢運算式總是以from子句開始,以select或者group子句結束。From子句定義了查詢的範圍變數(range variable),可以認為該變數是對輸入sequence的一個遍曆,就像foreach做的那樣。下面這幅圖描述了查詢運算式的完整文法:

當然,.NET公用語言運行庫(CLR)並不具有查詢文法的概念。編譯器會在程式編譯時間把查詢運算式轉換為方法文法,即對擴充方法的調用。這意味著,我們用查詢運算式寫出來的LINQ查詢都有等價的方法文法。對於上例中的查詢運算式,編譯器會轉換成下面的方法文法:

            IEnumerable<string> query = names
.Where (n => n.Contains("a"))
.OrderBy(n => n.Length)
.Select (n => n.ToUpper());

然後,應用編譯器對於方法文法的處理規則,上面的Where, OrderBy, Select查詢運算子會綁定到Enumerable類中的相應擴充方法。

範圍變數

範圍變數是緊隨from關鍵字之後定義的變數,一個範圍變數指向當前操作符所對應的輸入sequence中的當前元素。在我們的樣本中,範圍變數出現在每一個查詢子句中,但要注意的是,變數實際是對不同sequence的遍曆,因為Where、OrderBy、Select會有不同的輸入sequence:

            IEnumerable<string> query =
from n in names //n是我們定義的範圍變數
where n.Contains("a") //n直接來自names array
orderby n.Length //n來自filter之後的subsequent
select n.ToUpper(); //n來自OrderBy之後的subsequent

當 編譯器把上面的查詢文法翻譯成方法文法後,我們會更清楚的看到範圍變數的這種行為:

            IEnumerable<string> query2 = names
.Where(n => n.Contains("a")) //n直接來自names array
.OrderBy(n => n.Length) //n來自filter之後的subsequent
.Select(n => n.ToUpper()); //n來自OrderBy之後的subsequent

除了from關鍵字後面的範圍變數,查詢運算式還允許我們通過下面的子句引入新的範圍變數:

  • let
  • into
  • 額外的from子句

稍後我們會在“LINQ中的子查詢、建立策略和資料轉換”一篇中討論他們的使用方法和適用情境。

查詢運算式和方法文法

查詢運算式和方法文法各有所長。對下面的情境來講,用查詢運算式寫出來得查詢會更加簡潔:

  • 使用let關鍵字引入新的範圍變數
  • 在SelectMany、Join或GroupJoin後引用外部範圍變數時

在簡單的使用Where、OrderyBy、Select時,兩種文法結構並沒有大的差別,此時可以根據你的喜好任意選擇。

對於只有單個查詢運算子組成的查詢,方法文法會更加簡短和易於理解。

最後,對於沒有對應查詢運算式關鍵字的查詢運算子,我們就只能選擇方法文法了。下面是存在對應查詢運算式關鍵字的運算子:Where、Select、SelectMany、OrderBy、ThenBy、OrderByDescending、ThenByDescending、GroupBy、Join、GroupJoin。

組合查詢文法

當一個查詢運算子沒有對應的查詢文法時,我們可以組合使用查詢文法和方法文法。唯一的約束是查詢中的每一個查詢文法部分必須是完整的,如以from開始以select或group結束。如下例:

            string[] names = { "Tom", "Dick", "Harry", "Mary", "Jay" };

// 計算包含字母”a”的姓名總數
int matches = (from n in names where n.Contains("a") select n).Count(); // 3
// 按字母順序排序的第一個名字
string first = (from n in names orderby n select n).First(); // Dick

這種組合文法通常在書寫更加複雜的查詢時會具有優勢,像上面這種簡單的查詢,我們只需要使用方法文法就能收到很好的效果:

             int matches = names.Where(n => n.Contains("a")).Count();    // 3
string first = (names.OrderBy(n => n)).First(); // Dick

 

系列部落格導航:

LINQ之路系列部落格導航

LINQ之路 1:LINQ介紹

LINQ之路 2:C# 3.0的語言功能(上)

LINQ之路 3:C# 3.0的語言功能(下)

LINQ之路 4:LINQ方法文法

LINQ之路 5:LINQ查詢運算式

LINQ之路 6:順延強制(Deferred Execution)

LINQ之路 7:子查詢、建立策略和資料轉換

LINQ之路 8:解釋查詢(Interpreted Queries)

LINQ之路 9:LINQ to SQL 和 Entity Framework(上)

LINQ之路10:LINQ to SQL 和 Entity Framework(下)

LINQ之路11:LINQ Operators之過濾(Filtering)

LINQ之路12:LINQ Operators之資料轉換(Projecting)

LINQ之路13:LINQ Operators之串連(Joining)

LINQ之路14:LINQ Operators之排序和分組(Ordering and Grouping)

LINQ之路15:LINQ Operators之元素運算子、集合方法、量詞方法

LINQ之路16:LINQ Operators之集合運算子、Zip操作符、轉換方法、產生器方法

LINQ之路17:LINQ to XML之X-DOM介紹

LINQ之路18:LINQ to XML之導航和查詢

LINQ之路19:LINQ to XML之X-DOM更新、和Value屬性互動

LINQ之路20:LINQ to XML之Documents、Declarations和Namespaces

LINQ之路21:LINQ to XML之產生X-DOM(Projecting)

LINQ之路系列部落格後記

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.