過濾Filtering
Where: 返回滿足給定條件的子集,SQL對應語法也是Where
Take: 返回前N條記錄,丟棄剩余部分,SQL對應語法為Where ROW_NUMBER()或者TOP n子查詢
Skip:跳過前N條記錄, 返回剩余部分, SQL對應語法為Where ROW_NUMBER()或者NOT IN(Select Top N…)
TakeWhile:返回輸入序列中的所有元素直到斷言等於true,無SQL對應語法
SkipWHile:跳過輸入序列中的元素直到斷言等於true, 返回剩下的所有元素, 無SQL對應語法
Distinct:返回無重復的集合元素,SQL對應語法為Select Distinct…
使用這些過濾方法, 你總是會得到與原始輸入序列相等或者更少元素的輸出序列,而不可能得到更多的元素.得到的這些元素與原先的元素是一致, 中間並沒有做任何的轉換.
Where
參數列表:
源序列: IEnumerable
斷言: TSource => bool or (TSource, int) => bool(LINQ to SQL不支持)
實例:
1: string[] names = { “James”,“Jack”,“Hendry”,“Mary”,“David” };
2:
3: IEnumerable<string> query =
4:
5: names.Where (name => name.EndsWith (“y”));
6:
7:
8:
9: foreach(var s in query)
10:
11: Console.WriteLine(s);
12:
13: // Result: hendry, Mary
使用復合查詢語法:
1: IEnumerable<string> query = from n in names
2:
3: where n.EndsWith (“y”)
4:
5: select n;
在一個查詢中, Where可以出現多次, 使用let可以將他們分離開:
1: IEnumerable<string> query = from n in names
2:
3: where n.Length > 3
4:
5: let u = n.ToUpper( )
6:
7: where u.EndsWith (“Y”)
8:
9: select u; // Result: { “HENDRY”, “MARY” }
索引過濾
Where的另外一個斷言一個int類型作為其第二個參數, 這個參數代表當前元素在輸入序列中的索引位置, 斷言可以使用這個信息來做過濾決定.例如:
1: IEnumerable<string> query =
2:
3: names.Where ((n, i) => i % 2 == 0);
4:
5: foreach(var s in query)
6:
7: Console.WriteLine(s);
8:
9: // Result: James, Hendry, David
這裡只過濾偶數位置的元素,LINQ to SQL不支持此種過濾.
LINQ to SQL當中的Where
以下的方法會被轉換為SQL當中的like操作符:
Contains, StartsWith, EndsWith
例如, c.Name.Contains(“abc”)被翻譯成customer.Name LIKE ‘%abc%’(如果要更加精確,可以使用參數化版本). 也可以使用SqlMethods.Like來執行更復雜的比較.你可以使用String上的CompareTo方法來執行字符順序比較, 此方法映射到SQL的<和>操作符:
1: dataContext.Purchase.Where(p=>p.Description.CompareTo(“c”) < 0);
LINQ to SQL也允許你應用Contains操作符對本地集合進行過濾操作, 例如:
1: string[] chosenOnes = { “Tom”, “Jay” };
2:
3: from c in dataContext.Customers
4:
5: where chosenOnes.Contains (c.Name)
其映射到SQL的in操作符:
WHERE customer.Name IN (“Tom”, “Jay”)
Take和Skip
參數列表:
源序列: IEnumerable
被take或者skip的元素數量: int
Take使用前n個元素並丟棄剩余的元素, skip丟棄前n個元素並接受剩余的部分. 當你開發一個web頁的時候這兩個元素是很有用的, 它允許用戶查看一個包含大量匹配數據的集合.例如, 假設用戶使用短語”LINQ”查詢一個圖書數據庫並且得到100個匹配記錄, 下例返回了前20條:
1: IQueryable query = dataContext.Books
2:
3: .Where (b => b.Title.Contains (“LINQ”))
4:
5: .OrderBy (b => b.Title)
6:
7: .Take (20);
解析來的這個查詢返回了第21到40條:
1: IQueryable query = dataContext.Books
2:
3: .Where (b => b.Title.Contains (“LINQ”))
4:
5: .OrderBy (b => b.Title)
6:
7: .Skip (20).Take (20);
在SQL SERVER 2005當中,LINQ to SQL將Take和Skip翻譯成ROW_NUMBER函數, 而在SQL SERVER2000中則對應到top n子查詢.
TakeWhile和SkipWhile
參數列表:
源序列: IEnumberable
斷言: TSource=>bool 或者(TSource, int) => bool
TakeWhile枚舉輸入序列, emit每一個元素知道給定的斷言等於true, 然後丟棄所有剩余的元素:
1: int[] numbers = { 3, 5, 2, 234, 4, 1 };
2:
3: var takeWhileSmall = numbers.TakeWhile (n => n < 100);
4:
5: // RESULT: { 3, 5, 2 }
SkipWhile枚舉輸入序列,忽略每一個元素知道給定的斷言等於true,然後返回所有剩余的元素
1: int[] numbers = { 3, 5, 2, 234, 4, 1 };
2:
3: var skipWhileSmall = numbers.SkipWhile (n => n < 100);
4:
5: // RESULT: { 234, 4, 1 }
TakeWhile和SkipWhile沒有SQL的對應翻譯,因此如果你就其應用於LINQ to SQL當中將會得到一個運行時錯誤.
Distinct
Distinct返回從輸入序列中剝離了重復元素的序列.如下例:
1: char[] distinctLetters =
2:
3: “HelloWorld”.Distinct().ToArray( );
4:
5: string s = new string (distinctLetters); // HeloWrd
我們可以直接對string調用LINQ方法因為string實現了IEnumerable
待續!