LINQ之路 5 LINQ查詢表示式

2021-06-16 18:17:40 字數 3070 閱讀 9972

書寫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)

;ienumerablequery =

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 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:

ienumerablequery =

from n in names //n是我們定義的範圍變數

where n.contains("a") //n直接來自names array

orderby n.length //n來自filter之後的subsequent

select n.toupper(); //n來自orderby之後的subsequent

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

ienumerablequery2 = names

.where(n => n.contains("a")) //n直接來自names array

.orderby(n => n.length) //n來自filter之後的subsequent

.select(n => n.toupper()); //n來自orderby之後的subsequent

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

稍後我們會在「linq中的子查詢、建立策略和資料轉換」一篇中討論他們的使用方法和適用場景。

查詢表示式和方法語法各有所長。對下面的場景來講,用查詢表示式寫出來得查詢會更加簡潔:

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

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

最後,對於沒有對應查詢表示式關鍵字的查詢運算子,我們就只能選擇方法語法了。下面是存在對應查詢表示式關鍵字的運算子:where、select、selectmany、orderby、thenby、orderbydescending、thenbydescending、groupby、join、groupjoin。

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

string names = ;

// 計算包含字母」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之路 5 LINQ查詢表示式

書寫linq查詢時又兩種語法可供選擇 方法語法 fluent syntax 和查詢表示式 query expression linq方法語法的本質是通過擴充套件方法和lambda表示式來建立查詢。c 3.0對於linq表示式還引入了宣告式的查詢表示式,也叫查詢語法,通常來講,它是建立linq查詢的更...

LINQ 之 基本 LINQ 查詢操作

在 linq 查詢中,第一步是指定資料來源。像在大多數程式語言中一樣,必須先宣告變數,才能使用它。在 linq 查詢中,最先使用from子句的目的是引入資料來源和範圍變數。queryallcustomers 是 ienumerable型別 資料來源 customers 和範圍變數 cust var ...

查詢表示式 LINQ 簡介

在上兩篇我介紹了c 3.0新語特性和改進,這些新特性在我們編寫程式時為我們提供了非常大的幫助。從這篇開始,我們開始一起來 linq。linq是language integrated query的簡稱,它是整合在.net程式語言中的一種特性。已成為程式語言的乙個組成部分,在編寫程式時可以得到很好的編譯...