C# LINQ查询表达式用法对应Lambda表达式

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

相关文章
相关标签/搜索