程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> LINQ學習筆記:復合查詢和Lambda表達式語法

LINQ學習筆記:復合查詢和Lambda表達式語法

編輯:關於.NET

復合查詢

在前一節中, 我們寫了一個查詢來將分解那些包含一個字母a, 按長度排序, 並且最後轉換成大寫的字符串. 我們還有另外一種復合查詢的寫法:

   1: //前面我們使用的寫法
   2:     string[] names = { "James","Jack","Harris"};
   3:  
   4:     IEnumerable<string> query = names.Where(n => n.Contains ("a"))
   5:     .OrderBy (n => n.Length).Select  (n => n.ToUpper( ));
   6:  
   7: //組合查詢的寫法
   8:     string[] names = { "James","Jack","Harris"};
   9: IEnumerable<string> q = from n in names where n.Contains("a")
  10:                     orderby n.Length
  11:                     select n.ToUpper();
  12:                             
  13: foreach(string s in q)
  14:         Console.Write(s + ","); //JACK,JAMES,HARRIS,

 

一個復合查詢總是開始於from語句結束於select或者group語句. from語句聲明了一個迭代變量, 此變量代表輸入序列中的每一個元素, 類似foreach語法中的變量. 編譯器會將復合查詢翻譯成Lambda表達式, 類似於foreach表達式會被翻譯成調用GetEnumerator和MoveNext方法. 這意味著任何你可以使用的復合查詢同樣也可以使用Lambda表達式來完成. 例如上面的例子, 編譯器將會翻譯成這樣:

   1: IEnumerable<string> q = names
   2:   .Where(n => n.Contains ("a"))
   3:   .OrderBy(n => n.Length)
   4:   .Select(n => n.ToUpper());

 

迭代變量

緊跟在from關鍵字之後的標識符稱為迭代變量, 在我們的例子中, 迭代變量n出現在每一個查詢中的每一個從句. 然後, 此變量實際上枚舉了每一個從句中的不同序列中的元素:

   1: from    n in names       // n 是我們的迭代變量
   2: where   n.Contains ("a") // n = 直接來自於數組
   3: orderby n.Length         // n = 被過濾後的
   4: select  n.ToUpper();   // n = 排序過的

 

如果檢查一下編譯器幫我們生成的使用Lambda表達式的版本就可以看得更加清晰一點:

   1: names.Where   (n => n.Contains ("a"))
   2:      .OrderBy (n => n.Length)
   3:      .Select  (n => n.ToUpper());

 

n都是只屬於各自Lambda表達式的范圍裡面的.

查詢語法 VS SQL語法

LINQ的復合查詢語法看起來和SQL語法非常像, 然後他們是非常不同的. 一個LINQ查詢說到底還是一個C#表達式, 因為必須要遵循標准的C#規則. 例如, 在LINQ中, 你不能使用一個未聲明的變量. 而在SQL中, 在from語句定義之前你已經可以在select中引用一個表的別名了.

在LINQ中的子查詢僅僅是另外一個C#表達式, 因此並不需要有什麼特殊的語法. 而子查詢在SQL當中通常要受到一些特殊規則的限制.

在LINQ中, 整個數據處理流程是從左到右的. 而在SQL中, 這個順序則更加隨機.

一個LINQ查詢構成一個傳送帶, 或者一個管道, 其中的操作符接受和處理有序序列. 而SQL查詢則構成的語法網更多的是處理無序集合.

查詢語法和 Lambda表達式

復合查詢和Lambda表達式語法更有優點. 復合查詢對於符合以下情況的查詢更加簡單一些:

1. let從句來一個迭代變量後用於代表一個新的變量

   1: var list = new List<int>() { 1, 2, 3 };
   2: var query = from i in list
   3:             let j = i + 2
   4:             let k = j * j
   5:             select new { i, j, k };

 

2. SelectMany, Join或者GroupJoin緊跟著一個外部的迭代變量引用

至於Where, OrderBy和Select的使用, 兩種表達語法都可以工作的很好, 如何使用, 更多的取決於個人習慣.

對於那些只由單一操作符構成的查詢來說, Lambda表達式語法更加簡短,簡潔一點.

最後, 有很多的操作符是沒有對應的復合查詢關鍵字的, 對於這些操作符你只能使用Lambda表達式語法, 或者至少部分使用, 它們是:

Where, Select, SelectManager, OrderBy, ThenBy, OrderByDescending, ThenByDescending, Group, Join, GroupJoin

混合的查詢語法

如果一個查詢操作符沒有對應的復合查詢支持, 你可以混合使用復合查詢和Lambda表達式語法. 唯一的限制是每一個復合組件都必須被完成(例如從一個form從句開始並且結束於一個select或者group從句).

例如:

   1: string[] names = { "James","Jack","Harris"};
   2: int myCount = (from n in names
   3:                  where n.Contains ("J")
   4:                  select n
   5:                 ).Count();
   6: Console.WriteLine(myCount); //2

 

有一點是非常重要的, 你不能單一的偏向於喜歡復合查詢語法或者Lambda表達式語法, 更多的應該是根據功能的需要和簡單性來做選擇. 待續!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved