- LINQ基本查詢操作符-獲取數據
(1) select() 語法是:
public static IEnumerable<TResult> select<TSource,TResult>(
this IEnumerbale<TSource> source.
Func<TSource,TResult> selector)
說明:1) select方法本身是一個泛型擴展方法
2) 它作用於IEnumerable<TSource>類型
3) 他只接受一個Func<TSource,TResult>類型參數
4) Func<TSource,TResult>是一個泛型委托,位於System名字的空間下,System.Core.dll中,在這里Selector是一個提取器。
(2) 舉例說明,先定義一個靜態類ExtraClass,然后再靜態類中在定義一個靜態的擴展方法,實現輸出信息。代碼如下:
public static class ExtraClass
{
//為IEnumerable提供輸出的方法
public static void Print(this IEnumerable<string> ie)
{
IEnumerator<string> result = ie.GetEnumerator();
while (result.MoveNext())
{
MessageBox.Show(result.Current);
}
}
}
然后如圖所示,單擊圖上的按鈕事件,在按鈕事件中的代碼是:

此事件下面的代碼實現了將一個泛型集合中的數據循環顯示出來,代碼如下:
List<string> persons = new List<string>();
persons.Add("zhang san");
persons.Add("zhang san feng");
persons.Add("li si");
persons.Add("wang wu");
persons.Add("wang liu");
persons.Add("li ba");
persons.Add("lao wu");
persons.Add("zhang xx");
//輸出persons里面的所有的元素
var result = persons.Select(p => p);
result.Print();
執行結果是按順序循環輸出。
2. LINQ基本查詢操作符-過濾數據
(1) where() 語法是:
public static IEnumerable<TSource> where<TSource>(
this IEnumerable<TSource> source,
Func<TSource,bool> predicate)
說明:1) where方法是一個泛型擴展方法
2) 它和select()一樣作用與IEnumerable<TSource>類型
3) 它只接受一個Func<TSource,bool>泛型委托參數,在這里predicate是一個判斷條件。
(2) 舉例說明,還是上面的例子,使用那個泛型集合,實現按照一定的條件輸出信息。先創建一個方法,實現輸出姓“zhang”的人的信息,代碼如下:
public bool Judge(string s)
{
if (s.StartsWith("zhang"))
{
return true;
}
return false;
}
在select控件的事件下面用LINQ代碼輸出只是姓張的各種各樣的實現代碼:
//輸出persons里面姓“zhang”的人
//var result = persons.Where(p => p.StartsWith("zhang")); //第一種方法
//var result = persons.Select(p => p).Where(p => p.StartsWith("zhang")); //第二種方法
//var result = persons.Where(p => p.StartsWith("zhang")).Select(p => p); //第三種方法
var result = persons.Where(p => Judge(p)); //第四種方法
result.Print();
3. LINQ基本查詢操作符-排序數據
(1) OrderBy() 語法是:
pblic static IOrderedEnumerable<TSource> orderBy<TSource,TKey>(
this IEnumerable<TSource> source
Func<TSource,TKey> keySelector)
注:1) orderBy方法也是一個泛型擴展方法
2) 它和select()一樣作用與IEnumerable<TSource>類型
3) 它只接收一個Func<TSource,Tkey>類型參數,在這里keySelctor指定要排序的字段。
4) 如果想要降序排列可以使用orderbyDescending方法。
(2) 舉例說明,同上例,實現排序的代碼如下:
//var result = persons.OrderBy(p => p);
//按照名字的最后一個字母排序
//var result = persons.OrderBy(p => p.Substring(p.Length - 1, 1)).Select(p => p);
//降序排列
var result = persons.OrderByDescending(p => p);
result.Print();
- Linq基本查詢操作符-分組數據
(1) GroupBy() 語法是:
public static IEnumerable<IGrouping<Tkey,TSource>>
GroupBy<TSource,TKey>(
this IEnumerable<TSource> source,
Func<TSource,TKey> keySelector )
說明:1) GroupBy()方式和OrderBy()方式非常類似,它也是一個泛型擴展方法。
2) 它和OrderBy()一樣作用與IEnumerable<TSource>類型。
3) 它只接受一個Func<TSource,TKey>類型參數,在這里keySelector指定要分組的字段。
(2) 舉例說明,同上例,實現分組的代碼是:
//分組---按照姓名來分組¦--取出姓名中的空格前的部分
var result = persons.GroupBy(p => p.Split(new char[] { ' ' })[0]);
foreach (var group in result)
{
Console.WriteLine("姓:" + group.Key);
foreach (var name in group)
{
Console.WriteLine("\t" + name);
}
Console.WriteLine();
}
- 查詢執行的時機
(1) 從前面的試驗中,我們發現一次查詢實際上經過以下3步。
1) 第一步:獲取數據源 int[] numbers=new int[]{3,45,65,76,2,434,54,65,76,76,65,43};
2) 第二步:定義查詢 var even=numbers.Where(p=>p%2==0).Select(p=>{
Console.WriteLine(“Hi!”+p.ToString());
return p; });
3) 第三步:執行查詢 foreach(var item in even){ }
- 查詢執行的時機小節
(1) 查詢分為以下三步,獲取數據源,定義查詢,執行查詢
(2) 定義查詢后,查詢直到需要枚舉結果時才被真正執行,這種方法稱為”延遲執行”。
(3) 當查詢結果返回單一值時,查詢立即執行。舉例,如代碼:
//查詢時機---當返回值為單值時馬上執行語句,負責延遲執行
var result = persons.Select(p => p).Count();
Console.WriteLine("個數是" + result);
(4) 因此,可以通過以下技巧在定義查詢時就強制執行查詢
- Linq查詢的兩種方式
(1) Method syntax,查詢方法方式
主要利用System.Linq.Enumerable類中定義的擴展方法和Lambda表達式方式進行查詢。
(2) Query syntax ,查詢語句方式
- 查詢語句VS查詢方法
注:查詢語句和查詢方法存在着緊密的關系
(1) CLR本身並不理解查詢語句,它只理解查詢方法。
(2) 編譯器負責在編譯時將查詢語句翻譯為查詢方法。
(3) 大部分查詢方法都有對應的查詢語句形式,如:Select()對應select,OrderBy()對應orderby。
(4)部分查詢方法目前在C#中還沒有對應的查詢語句:如:Count()和Max()這時只能采用以下替代方案
1) 查詢方法
2) 查詢語句+查詢方法的混合方式
(5) 一般情況下,建議使用可讀性更好的查詢語句。舉例說明:
還是用上面多定義的泛型集合數組persons,用查詢語句實現幾個簡單的功能,代碼如下:
//輸出persons中的所有的元素
var result = from p in persons select p;
//輸出persons中姓zhang的人----語句和方法的混合編排?
var result = (from p in persons select p).Where(p => p.StartsWith("zhang"));
//排序
var result = from p in persons orderby p select p;
result.Print();
- 高級查詢方法
(1) 聚合類 Count(),Max()/Min(),Average(),Sum()。舉例說明:
重新定義一個數組來實現上面的各種各樣的方法,代碼如下:
//LINQ to Objects查詢高級方法
//數組數據arr
int[] arr = { 23, 34, 5, 5, 23, 45, 65, 33, 43, 76, 67, 87 };
//聚合類
Console.WriteLine("arr的最大值: + arr.Max());
Console.WriteLine("arr的最小值¦: " + arr.Min());
Console.WriteLine("arr的平均值¦: " + arr.Average());
Console.WriteLine("arr的數組元素個是" + arr.Count());
Console.WriteLine("arr的總和是: " + arr.Sum());
(2) 排序類 thenBy() 代碼如下:
//排序類
var result = arr.OrderBy(p => p.ToString().Substring(0, 1));
//2次排序混編模式沒有達到要求
var result = arr.OrderBy(p => p.ToString().Substring(0, 1)).ThenBy(p => p);
//按照語句排序
var t = arr.OrderBy(p => p.ToString().Substring(0, 1));
var result = from p in t orderby p descending select p;
(3) 分區類 Take,TakeWhile,Skip,SkipWhile 代碼如下:
//分區類
var result = arr.Skip(3).Take(3); //跳過三個值取三個值
var result = arr.Skip(3); //跳過幾個值
var result = arr.SkipWhile(p => p > 4); //方法體部分是該Linq語句不在往后執行的條件,當第一次遇到條件成立時,取剩下的所有元素
var result = arr.TakeWhile(p => p > 4); //方法體部分是該Linq語句提取數據的條件,當第一次遇到條件不成立的情況就停止執行
(4) 集合類 Distinct 代碼如下:
//集合類
var result = arr.Distinct();
(5) 生成類 Range,Repeat 代碼如下:
//生成類-----靜態類
var result = System.Linq.Enumerable.Range(10, 50);
var result = System.Linq.Enumerable.Range('a', 50); //生成連續的序列
var result = System.Linq.Enumerable.Repeat(40, 10);
result.Print();
- 生成類查詢方法小結
注:使用生成類查詢方法時,需要注意以下幾點:
(1) 和其它幾類方法不同,Range/Repeat不是擴展方法,而是普通的靜態方法
(2) Range只能產生整數序列。
(3) Repeat可以產生泛型序列。
(4) 所有的查詢方法都存放在System.Linq.Enumerable靜態類中。
