LINQ 語言集成查詢(Language INtegrated Query)作為.net平臺的一項查詢技術,給我們的開發帶來了極大地方便。本人用2.0的平臺時間較長,對LINQ用的不是太多。LINQ查詢的數據源:實現IEnumberable<T>接口的對象、關系數據庫、數據集(DataSets)以及xml文檔。最近偶使用到它,談談一下使用基礎與體會。
LINQ與T-Sql語法類似,有一些數據庫基礎的理解它應該不難。下面主要從我使用到的幾個函數等來進行說明。
1、Except
2、Cast
3. Take、TakeWhile
4、Skip、SkipWhile
5、Lambda表達式基礎
首先,還是從最基本的查詢語法說起。由于LINQ查詢結果是IEnumerable<T>,接收返回結果時定義為var比較簡潔。最基本的查詢語法為:from [parameters] in [dataSource] select [result].示例代碼和截圖還是最直接:
#代碼
int[] arr1 = new int[] {1, 2, 3, 4, 5};
int[] arr2 = new int[] {1, 2, 5, };
var result = from a in arr1
join b in arr2 on a equals b into list
from r in list
select r;
foreach(var v in result)
{
Console.WriteLine(v.ToString());
}
輸出結果如下:
以上的查詢是將兩個集合中相同的元素查出來,放入到list中,然后再從list中進行查詢。
在Select中,也可以自定義需要選擇的結果。如需要找出兩個集合中相同元素的長度,代碼如下:
string[] list1 = new string[] {"ab", "bc", "abd", "aaaa"};
string[] list2 = new string[] { "ab", "abd", "aabb","bb" };
var query = from s in list1
join m in list2 on s equals m
select new {s.Length};
foreach( var len in query)
{
Console.WriteLine(len.Length);
}
輸出結果如下:
2,3
在查詢時候用判斷元素相等用的是equals,而不是編程語言中的"=="或者T-SQL中的"=",有點特別。
1、Except:返回查詢兩個集合中差異的元素。
var dif = arr1.Except(arr2);
foreach (var item in dif)
{
Console.WriteLine(item);
}
這樣dif就包含3,4兩個元素
2、Cast:對數據源中元素進行類型轉化,轉化的目標類型為Cast指定的泛型。
Console.WriteLine("Cast************");
object[] obj = new object[] {1,2,3};
var intResult = obj.Cast<int>();
foreach( var item in intResult)
{
Console.WriteLine("item :{0}",item.GetType().ToString());
Console.WriteLine(item);
}
輸出如下:
3. Take、TakeWhile:Take(int i)從數據源起始位置返回指定數量的個數。如果指定的參數為-1,則返回為0,若指定的參數大于數據源的個數,則返回全部數據。TakeWhile需要指定委托來實現獲取元素.它有兩個重載。一個參數的委托MSDN給出的解釋如下:
【此方法通過使用延遲執行實現。即時返回值為一個對象,該對象存儲執行操作所需的所有信息。只有通過直接調用對象的 GetEnumerator 方法或使用 Visual C# 中的 foreach(或 Visual Basic 中的 For Each)來枚舉該對象時,才執行此方法表示的查詢。
TakeWhile<(Of <(TSource>)>)(IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, Boolean>)>)) 方法使用 PRedicate 對 source 中的每個元素進行測試,如果結果為 true,則生成該元素。當謂詞函數對某個元素返回 false 或 source 中不再包含元素時,枚舉將停止?!?/P>
兩個參數的委托第一個參數表示要測試的元素。第二個參數表示 source 中元素的從零開始的索引
注意其中標紅的部分:意思就是說,TakeWhile會枚舉集合中的元素,通過委托的函數進行操作。但是如果中途某個元素返回false后將停止對集合中后續的元素繼續枚舉,并且返回的結果中包含的元素為返回False前取出的所有元素。當然當枚舉完集合時,肯定也會停止繼續枚舉。
int[] arr1 = {10, 1, 2, 3, 4, 5};
IEnumerable<int> query = arr1.TakeWhile(Compare);
這樣query中只包含10一個結果。這是因為當枚舉到1返回了false,TakeWhile停止了對集合的枚舉。
同樣,通過Take操作,可以查詢出類似SQL數據庫中Top關鍵字的結果。如果想每次取出集合中的N個元素,我們可以arr1.Take(i*N).Except(arr1.Take((i-1)*N)。
4、Skip、SkipWhile :Skip返回從數據源中跳過某元素后的集合。
SkipWhile需要通過委托來用于測試每個元素是否滿足條件的函數。MSDN給出的解釋如下:
【只要滿足指定的條件,就跳過序列中的元素,然后返回剩余元素。
通過使用延遲執行實現 SkipWhile<(Of <(TSource>)>)(IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, Boolean>)>)) 方法。即時返回值為一個對象,該對象存儲執行操作所需的所有信息。只有通過直接調用對象的 GetEnumerator 方法或使用 Visual C# 中的 foreach(或 Visual Basic 中的 For Each)來枚舉該對象時,才執行此方法表示的查詢。
此方法使用 predicate 測試 source 的每個元素,如果結果為 true,則跳過該元素。謂詞函數針對一個元素返回 false 后,則生成該元素及 source 中的剩余元素,并且不再調用 predicate。
如果 predicate 為序列中的所有元素返回 true,則返回一個空 IEnumerable<(Of <(T>)>)。】
注意:同TakeWhile一樣,對集合中的元素進行枚舉時,如果返回True則跳過此元素。如果返回False,則返回從返回False的元素開始到集合的剩余元素。即返回False時停止了對集合的枚舉。如果集合中的每個元素都返回True則返回一個空的集合
如: int[] arr1 = {10, 1, 2, 3, 4, 5};var query1 = arr1.SkipWhile(n => n > 9);
foreach ( var item in query1)
{
Console.WriteLine(item);
}
輸出為:1, 2, 3, 4, 5。
5、Lambda表達式
Lambda是一個匿名函數,可以包含表達式或者語句塊。它都是用Lambda運算符“=>”。念做“goes to”。如上述TakeWhile、SkipWhile都是用了 n => n > 9 Lambda表達式。在arr1.SkipWhile(n => n > 9)中,體會是n就是arr1中某一個元素,只是編譯器會根據arr1定義的類型識別匿名參數n的類型。
聰明的人們
新聞熱點
疑難解答