HOW TO:在 C# 中撰寫 LINQ 查詢
更新:2007 年 11 月
本主題說明可在 C# 中撰寫 LINQ 查詢的三種方式:
使用查詢語法。
使用方法語法。
使用查詢語法和方法語法的組合。
下列範例使用上列各種方法來示範幾種簡單的 LINQ 查詢。一般的規則是盡可能使用 (1),必要時才使用 (2) 和 (3)。
注意事項: |
---|
雖然這些查詢是在記憶體中的集合上操作,但是基本語法與 LINQ to SQL 和 LINQ to XML 中使用的語法相同。 |
範例
查詢語法
撰寫多數查詢的建議方式是使用「查詢語法」(Query Syntax) 來建立「查詢運算式」(Query Expression)。下列範例顯示三個查詢運算式。第一個查詢運算式示範如何藉由套用具有 where 子句的條件來篩選或限制結果;它會傳回來源序列中值大於 7 或小於 3 的所有項目。第二個運算式示範如何排序傳回的結果。第三個運算式則示範如何依據索引鍵來群組結果;這項查詢會根據單字的第一個字母傳回兩個群組。
// Query #1.
List<int> numbers = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
// The query variable can also be implicitly typed by using var
IEnumerable<int> filteringQuery =
from num in numbers
where num < 3 || num > 7
select num;
// Query #2.
IEnumerable<int> orderingQuery =
from num in numbers
where num < 3 || num > 7
orderby num ascending
select num;
// Query #3.
string[] groupingQuery = { "carrots", "cabbage", "broccoli", "beans", "barley" };
IEnumerable<IGrouping<char, string>> queryFoodGroups =
from item in groupingQuery
group item by item[0];
請注意,這些查詢的型別都是 IEnumerable<T>。所有的查詢都可使用 var 來撰寫,如下列範例所示:
var query = from num in numbers...
在前述各個範例中,必須等到您逐一查看 foreach 陳述式中的查詢變數之後,才會實際執行查詢。如需詳細資訊,請參閱LINQ 查詢簡介。
方法語法
某些查詢作業必須以方法呼叫來表示。這種方法最常見的是傳回單一數值的方法,例如 Sum、Max、Min 和 Average 等。這些方法在任何查詢中永遠都是最後呼叫的方法,因為它們只代表單一值,而且不能當做其他查詢作業的來源。下列範例顯示查詢運算式中的方法呼叫:
List<int> numbers1 = new List<int>() { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
List<int> numbers2 = new List<int>() { 15, 14, 11, 13, 19, 18, 16, 17, 12, 10 };
// Query #4.
double average = numbers1.Average();
// Query #5.
IEnumerable<int> concatenationQuery = numbers1.Concat(numbers2);
如果方法具有參數,這些參數將以 Lambda 運算式的形式提供,如下列範例所示:
// Query #6.
IEnumerable<int> largeNumbersQuery = numbers2.Where(c => c > 15);
在前面的查詢中,只有查詢 #4 會立即執行。這是因為這項查詢會傳回單一值,而非泛型 IEnumerable<T> 集合。該方法本身必須使用 foreach 才能計算它的值。
前述每一項查詢都可使用 var 的隱含型別來撰寫,如下列範例所示:
// var is used for convenience in these queries
var average = numbers1.Average();
var concatenationQuery = numbers1.Concat(numbers2);
var largeNumbersQuery = numbers2.Where(c => c > 15);
混合查詢和方法語法
本範例示範如何在查詢子句的結果上使用方法語法。您只需將查詢運算式放在括號內,然後再套用點運算子並呼叫方法即可。在下列範例中,查詢 #7 會傳回值介於 3 到 7 之間的數值計數。不過,一般情況下最好使用第二個變數來存取方法呼叫的結果。透過這種方式,查詢就比較不會與查詢的結果混淆。
// Query #7.
// Using a query expression with method syntax
int numCount1 =
(from num in numbers1
where num < 3 || num > 7
select num).Count();
// Better: Create a new variable to store
// the method call result
IEnumerable<int> numbersQuery =
from num in numbers1
where num < 3 || num > 7
select num;
int numCount2 = numbersQuery.Count();
因為查詢 #7 會傳回單一值而非集合,所以查詢將會立即執行。
前述查詢可以使用內含 var 的隱含型別來撰寫,如下列範例所示:
var numCount = (from num in numbers...
此查詢可以使用下列方法語法來撰寫:
var numCount = numbers.Where(n => n < 3 || n > 7).Count();
此查詢也可以使用以下明確指定型別的方式來撰寫:
int numCount = numbers.Where(n => n < 3 || n > 7).Count();