iT邦幫忙

DAY 15
2

分享一些學習心得系列 第 15

LINQ自學筆記-打地基-查詢運算式

查詢運算式(Query Expressions)讓 .Net 開發人員可以將 LINQ 查詢語法寫成類似標準 SQL Script 樣式,讓許多開發人員可以迅速上手,是一個非常棒的設計,本篇將為大家介紹查詢運算式的相關知識。
自學筆記這系列是我自己學習的一些心得分享,歡迎指教。這系列的分享,會以 C# + 我比較熟的 Net 3.5 環境為主。
另外本系列預計至少會切成【打地基】和【語法應用】兩大部分做分享。打地基的部分,講的是 LINQ 的組成元素,這部分幾乎和 LINQ 無關,反而是 C# 2.0、C# 3.0 的一堆語言特性,例如:型別推斷、擴充方法、泛型、委派等等,不過都會把分享的範圍限制在和 LINQ 應用有直接相關功能。
PS. LINQ 自學筆記幾乎所有範例,都可直接複製到 LINQPad 4 上執行(大多是用 Statements 和 Program 模式)。因為它輕巧好用,功能強大,寫範例很方便,請大家自行到以下網址下載最新的 LINQPad:http://www.LINQpad.net/。
對大部分開發人員來講,Select – From – Where 這種資料庫查詢語法大家都很熟悉了,而 LINQ 的查詢運算式(Query Expressions)幾乎雷同,差別只在把 Select 放到最後,語法從「From」開始。根據網路上查到的資料,其實 LINQ 開發團隊,一開始的有嘗試使用 Select – From – Where 架構,但是這樣會因為資料來源在第二段,所以一開始 Select 的地方無法使用 IntelliSense,而且在欄位型別判斷上也會有困擾,所以最後調整為 Select 放最後面:
PS. 查詢運算式也稱之為查詢表達式。

void Main()
{
     //建立一組匿名型別陣列做為資料來源
    var customers = new[]{
     new {  Name = "小李", Discount = 5.0 },
     new {  Name = "老王", Discount = 3.0 },
     new {  Name = "阿華", Discount = 4.5 },
     new {  Name = "明明", Discount = 4.0 }
    };

    //定義類似 SQL Script 的 LINQ 查詢運算式,並設定輸出一組新的匿名型別清單
    var query =
       from c in customers
       where c.Discount > 3
       orderby c.Discount
       select new { c.Name, Perc = c.Discount / 100 };
    //執行查詢
    query.Dump();
}

上述程式碼先透過「型別推斷+匿名型別+物件初始化設定式」建立一組資料來源,然後使用 LINQ 查詢運算式撰寫查詢語句,最後再利用 LINQPad 提供的 Dump 方法將結果輸出。這裡的 Dump 方法,可視為以下 For each 的方法:

foreach (var x in query)
{
    Console.WriteLine(x);
}
Console.Read();

MSDN 對查詢運算式的說明如下:
「查詢運算式」(Query Expression) 是以查詢語法表示的查詢。 查詢運算式是第一級的語言建構, 它就像其他任何運算式一樣,而且可以在 C# 運算式適用的任何內容中使用。 查詢運算式是由一組子句組成,而這些子句都是以類似 SQL 或 XQuery 的宣告式語法撰寫而成。 每個子句也會包含一個或多個 C# 運算式,而這些運算式可能本身就是查詢運算式,或是包含查詢運算式。
查詢運算式必須以 from 子句開頭,並以 select 或 group 子句結尾。 在第一個 from 子句和最後的 select 或 group 子句中間,也可以包含下列一個或多個子句:where、orderby、join、let,甚至是額外的 from 子句。 您也可以使用 into 關鍵字,讓 join 或 group 子句的結果變成同一個查詢運算式中其他查詢子句的來源。

總結上述的說明,我們引用 C# In a Nutshell 的 LINQ 語法圖示:(http://www.albahari.com/nutshell/linqsyntax.aspx)

轉譯為程式碼如下:

IEnumerable<T> query-expression-identifier = 
    from identifier in expression
    let identifier = expression
    where boolean-expression
    join identifier in expression 
        on expression equals expression 
        into identifier
    orderby ordering-clause ascending|descending
    group expression by expression 
        into identifier
    select expression 
        into identifier

上述程式碼中,只有 from 和 select 兩個語法關鍵字是每個 LINQ 查詢運算式必備,其他都是選擇性使用。identifier 表示「識別子」,通常也就是個變數;expression 則是一個運算式,可能是一個儲存資料的 List<T>、簡單數學運算、字串處理等等(有時候其實就包裝成匿名委派了);ordering-caluse 則是排序子句,也就是要排序的欄位;除此之外都是 LINQ 的語法關鍵字,可搭配前面的圖示閱讀會更容易理解。


上一篇
LINQ自學筆記-打地基-LINQ工作對象
下一篇
LINQ自學筆記-打地基-方法架構查詢
系列文
分享一些學習心得30

尚未有邦友留言

立即登入留言