C#編程語言很是優美,我我的仍是很是贊同的。特別是在學習一段時間C#後發現確實在它的語法和美觀度來講確實要比其它編程語言強一些(也多是因爲VS編譯器的加持)用起來很是舒服,並且對於C#我以爲他最優美之處不只僅是語法糖方面還有就是體如今LINQ和Lambda表達式。html
本篇文簡單介紹一下關於C#當中LINQ表達式和其對應的Lambda表達式的用法,關於這兩部份內容的相關參考資料:數據庫
人民郵電出版社《C#程序設計及應用教程》(第3版)編程
博客園博客:《c# Linq查詢》c#
同時在介紹的時候我會盡可能挑出重要部分同時加上我本身的理解和認識,若有誤差還請指教。數組
首先先讓咱們看一下什麼是LINQ查詢表達式和Lambda表達式:dom
運行結果:編程語言
以上是對LINQ查詢表達式和Lambda表達式的一個簡單的應用,都是查詢stu列表中年齡大於等於20歲的結果而且把結果按照年齡降序排列。學習
因而可知Linq表達式和Lambda表達式並無什麼可比性,只是用Lambda能夠實現LINQ的查詢語句。spa
那與Lambda表達式相關的整條語句稱做什麼呢?在微軟並無給出官方的命名,在《深刻理解C#》中稱其爲「點標記」。線程
例子中主要以LINQ表達式爲主,LINQ表達式結構更爲清晰易於理解,同時也會給出對應的點標記寫法(全部的LINQ查詢表達式均可以轉成對應的點標記。反之,不是全部的點標記均可以轉成查詢表達式。),因此若是想要了解這部分的讀者也請往下看。本文會介紹LINQ查詢表達式用法以及對應的Lambda表達式。
LINQ查詢表達式是一組查詢技術的統稱,其主要思想是將各類查詢功能直接集成到C#語言中,不管是對象、XML、仍是數據庫均可以用LINQ編寫查詢語句。LINQ與傳統迭代技術實現的查詢優點在於更簡明、更易讀這種優點特別是在篩選多個條件時更爲顯著;使用不多的程序代碼便能實現複雜的查詢和篩選;無需修改或者是進行不多的修改就能移植到其它的數據源。LINQ查詢語句並不複雜而且與SQL語句有些相似,學習起來難度並不大。
接下來直接看LINQ查詢例子:
1 //如下爲例子中涉及查詢的數據 2 List<Student> stu = new List<Student>() 3 { 4 new Student(){Id = 1,Name = "王同窗",Age = 24}, 5 new Student(){Id = 2,Name = "王同窗",Age = 30}, 6 new Student(){Id = 3,Name = "王同窗",Age = 21}, 7 new Student(){Id = 4,Name = "趙同窗",Age = 20}, 8 new Student(){Id = 5,Name = "錢同窗",Age = 22}, 9 new Student(){Id = 6,Name = "孫同窗",Age = 23}, 10 new Student(){Id = 7,Name = "周同窗",Age = 23}, 11 new Student(){Id = 8,Name = "吳同窗",Age = 20}, 12 new Student(){Id = 9,Name = "鄭同窗",Age = 25}, 13 new Student(){Id = 10,Name = "蔣同窗",Age = 26} 14 };
查詢年齡是30歲的王同窗的信息:
1 //查詢年齡是30歲的王同窗的信息 2 var res = from t in stu 3 where t.Name == "王同窗" && t.Age == 30 4 select t; 5 6 //對應的Lambda表達式 7 //var res1 = stu.Where(t => t.Age == 30 && t.Name == "王同窗"); 8 9 foreach (var item in res)//顯示查詢結果 10 { 11 Console.Write("學號:"+item.Id+"\n姓名:"+item.Name+"\n年齡:"+item.Age); 12 }
運行結果:
LINQ查詢表達式必須以form子句開頭,而且必須以select或group子句結尾。在第一個from子句和最後一個select或group子句之間,查詢表達式能夠包含一個或者多個where、orderby、join、let甚至附加from子句。LINQ表達式總體的用法和SQL語句很像,在上面的例子中就能夠看出。
上面的例子的含義就是從數據源stu中查詢一個數據「t」,「t」知足的條件就是它的Name是王同窗同時它的Age是30,而後查詢這個「t」。LINQ查詢語句的返回值類型爲IEnumerable<T>,LINQ執行查詢時,通常利用foreach循環執行查詢獲得一個序列,這這種方式稱爲「延遲執行」。
什麼是「延遲執行」?仍是上面例子中的查詢:
1 //查詢年齡是30歲的王同窗的信息 2 var res = from t in stu 3 where t.Name == "王同窗" && t.Age == 30 4 select t; 5 //var res1 = stu.Where(t => t.Age == 30 && t.Name == "王同窗");Lambda表達式寫法 6 7 foreach (var item in res) 8 { 9 Console.Write("學號:"+item.Id+"\n姓名:"+item.Name+"\n年齡:"+item.Age); 10 } 11 12 Console.WriteLine("\n--------------------------------------------------------------------------"); 13 14 stu.Add(new Student(){Id = 11,Name = "王同窗",Age = 30}); 15 16 foreach (var item in res) 17 { 18 Console.Write("學號:" + item.Id + "\n姓名:" + item.Name + "\n年齡:" + item.Age); 19 Console.WriteLine(); 20 }
運行結果:
延遲查詢就是隻需構造一次查詢語句,能夠屢次使用。在List中添加新元素以後並無從新執行查詢操做,然而res中的結果卻根據List中元素的改變相應發生了改變。
從學生中選出年齡小於25歲而且按照年齡降序排列
1 //從學生中選出年齡小於25歲而且按照年齡降序排列 2 var res = from t in stu 3 where t.Age < 25 4 orderby t.Age descending 5 select t; 6 //var res1 = stu.Where(t => t.Age < 25).OrderByDescending(t => t.Age).Select(t => t);Lambda寫法 7 8 foreach (var item in res) 9 { 10 Console.Write("學號:" + item.Id + "\n姓名:" + item.Name + "\n年齡:" + item.Age); 11 Console.WriteLine(); 12 }
運行結果:
從學生中查詢姓王的同窗的信息而且按照年齡降序排列
1 //從學生中查詢姓王的同窗的信息而且按照年齡降序排列 2 var res = from t in stu 3 from n in t.Name 4 where n == '王'//名字中帶有王字 5 orderby t.Age descending 6 select t; 7 //var res1 = stu.Where(t => t.Name.IndexOf("王") == 0).OrderByDescending(t => t.Age);lambda表達式 8 9 foreach (var item in res) 10 { 11 Console.Write("學號:" + item.Id + "\n姓名:" + item.Name + "\n年齡:" + item.Age); 12 Console.WriteLine(); 13 }
運行結果:
學生信息按照年齡、Id進行排序
1 //參數越靠前,優先級越高 2 //先按age排序,當分數相同時再按id排序...依次類推 3 4 var res = from t in stu 5 orderby t.Age, t.Id 6 select t; 7 //var res1 = stu.OrderBy(t => t.Age).ThenBy(t => t.Id);Lambda表達式 8 9 foreach (var item in res) 10 { 11 Console.Write("學號:" + item.Id + "\n姓名:" + item.Name + "\n年齡:" + item.Age); 12 Console.WriteLine(); 13 }
運行結果:
按照年齡進行分組,查詢相同年齡數量大於2的內容
1 //按照年齡進行分組,查詢相同年齡數量大於2的內容 2 var res = from t in stu 3 group t by t.Age into s 4 where s.Count()>=2 5 select s; 6 //var res1 = stu.GroupBy(t => t.Age).Where(s => s.Count() >= 2);lambda表達式 7 8 foreach (var item in res) 9 { 10 foreach (var items in item) 11 { 12 Console.Write("學號:" + items.Id + "\n姓名:" + items.Name + "\n年齡:" + items.Age); 13 Console.WriteLine(); 14 } 15 Console.WriteLine(); 16 }
運行結果:
查詢出集合qSt中year等於集合qSc中year的元素並造成新的集合
1 List<s> pSt = new List<s>(); 2 pSt.Add(new s() { year = 1999, name = "小張" }); 3 pSt.Add(new s() { year = 2000, name = "小王" }); 4 pSt.Add(new s() { year = 2001, name = "小李" }); 5 pSt.Add(new s() { year = 2010, name = "小趙" }); 6 List<school> pSc = new List<school>(); 7 pSc.Add(new school() { year = 1999, name = "aaa" }); 8 pSc.Add(new school() { year = 2001, name = "bbb" }); 9 pSc.Add(new school() { year = 2002, name = "ccc" }); 10 pSc.Add(new school() { year = 2010, name = "ddd" }); 11 pSc.Add(new school() { year = 2012, name = "fff" }); 12 13 var res = from t1 in pSc 14 from t2 in pSt 15 where t1.year == t2.year 16 select new {year = t1.year, name = t1.name + t2.name}; 17 18 foreach (var item in res) 19 { 20 Console.Write("年:" + item.year + "姓名:" + item.name); 21 Console.WriteLine(); 22 }
運行結果:
並行linq
並行查詢能夠分解查詢的工做,使其分佈在多個線程上。當pc擁有多個cpu時,能夠看到並行查詢帶來的改進效果。並行LINQ適用於大型的集合查詢,並擁有必定的優點。使用System.Collections.Concurrent.Partitioner.Create能夠手動建立分區器。能夠粗魯的認爲並行linq對於大集合的查詢是優點比較明顯的。取消長時間運行的並行linq查詢能夠設置利用System.Threading.CancellationTokenSource設置取消操做。
1 Console.WriteLine("開始構造大數組..."); 2 //構造大數組 3 const int count = 100000000; 4 var data = new int[count]; 5 var r = new Random(); 6 for (int i = 0; i < count; i++) 7 { 8 data[i] = r.Next(40); 9 } 10 Console.WriteLine("開始計算..."); 11 var st = System.DateTime.Now; 12 var sum = (from x in data where x > 20 select x).Sum();//常規linq-耗時1.8641s 13 var st2 = System.DateTime.Now; 14 var sum2 = (from x2 in data.AsParallel() where x2 > 20 select x2).Sum();//並行查詢-耗時0.6620s 15 16 //var sum3 = data.AsParallel().Where(x3 => x3 > 20).Sum();//或並行查詢----x3 => x3 > 20(Lambda表達式) 17 var st3 = System.DateTime.Now; 18 19 /*Partitioner.Create 20 手動建立分區器以及終止LINQ查詢的方法能夠詳見文初的博客連接 21 Create具備多個重載,可依據需求進行分區*/ 22 23 var sum4 = (from c in System.Collections.Concurrent.Partitioner.Create(data, true).AsParallel() where c > 20 select c).Sum(); 24 25 var dt1 = st2 - st; 26 var dt2 = st3 - st2; 27 Console.WriteLine("常規linq耗時:{0}s", dt1.TotalSeconds.ToString()); 28 Console.WriteLine("並行linq耗時:{0}s", dt2.TotalSeconds.ToString()); 29 Console.ReadKey();
運行結果:
寫在最後,若是你對以上LINQ以及對應的Lambda的使用方法都已經瞭解那你已經初步瞭解了LINQ查詢表達式和Lambda表達式,這裏須要說明的一點是關於Lambda的使用方法並不只僅只限於進行查詢,他是一個主要用於簡化委託的代碼編寫形式,他用法遠比文中介紹的更加普遍,本文是爲了對比展示LINQ和Lambda。
以上內容歡迎指正交流。
原文出處:https://www.cnblogs.com/hellohxs/p/12266856.html