LINQ简介(二)
2011-10-12 19:44
190 查看
LINQ简介(二)
------Linq方法语法和Lambda表达式2.1 λ表达式
Lambda表达式用来实现一个匿名方法,其语法为:
(参数列表)=> 语句或语句块
这是一个简单的Lambda表达式: n=>n<1000;
运算符 “=>”称为λ表达式。这个表达式定义了一个方法(函数),其参数是n,如果n小于1000,该方法就返回ture,否则返回false。该方法是一个没有名称的匿名方法,仅在把λ表达式传给Linq方法时使用。
2.2 λ表达式在Linq中的使用
用Linq完成同一任务有多种方式, 但通常需要通过编程来实现。如上一章内容是使用Linq查询语法编写的。本章内容将重点介绍Linq的方法语法。
Linq拥有一系列扩展方法,用于集合、数组、查询结果等对象,不在需要from…where…select子句。回顾上一章内容的示例:
var result = from n in names where n.StartsWith("s") select n;
现在可以用方法语法来实现:
var result = names.Where(n => n.StartsWith("s"));
C#编译器把λ表达式编译成一个匿名方法,where()在names数组中的每一个元素上执行这个方法。如果λ表达式给某个元素返回true,该元素就包含在Where()返回的结果集中。
查询语法是Linq中编写查询的首选方式,但是一定要基本了解方法语法,因为一些Ling功能不能通过查询语法来使用,或者说使用方法语法比较简单。
2.2.1 用方法语法排序
对刚才的查询结果排序可以使用如下语句:
var result = names.OrderBy(n => n).Where(n => n.StartsWith("s"));
或者:
var result = names.Where(n => n.StartsWith("s")).OrderBy(n=>n);
方法调用的顺序不是固定的,只要Linq方法返回值为IEnumerable类型即可,可以按照容易理解的方式来使用。此规则适合于以后讲到的其他方法。
OrderBy()方法需要传入一个λ表达式用来告诉它用于排序的方法是什么,我们传送了最简单的λ表达式n=>n,因为只需要按照元素本身排序。还可以向上一章所讲那样按照最后一个字母进行排序,传给OrderBy()方法一个这样的表达式:n=>n.Substring(n.Length-1)
为了给元素逆序排序,可以调用OrderByDescending()方法,使用方法和OrderBy()相同。
2.2.2 投射的方法语法
投射查询的方法语法版本是通过把Linq方法Select()的调用关联到我们调用的其他Linq方法上来实现的。例如要实现上一章示例五的功能,代码如下:
var result=list.Where(stu=>stu.Age==18).Select(stu=>new {stu.Name,stu.Age,stu.Class});
Select()方法用于方法语法的投射。
常见错误:
var result=list.Select(stu=>new stu.Name,stu.Age,
stu.Class}).Where(stu=>stu.Sex==’男’);
虽说方法的调用顺序不固定,但根据查询的特性,不适用与上面的查询。因为Sex属性并不包含在Select()投射创建的匿名类型(stu.Name,stu.Age,stu.Class)中,所以上述代码会在Where()方法上得到一个编译错误---匿名类型不包含Sex的定义。改成如下写法是正确的。
var result=list.Select(stu=>new stu.Name,stu.Age,
stu.Class}).Where(stu=>stu.Class==’50’);
2.2.3 Any和All
我们常常需要的另一类查询是确定数据是否满足某个条件,或者确保所有的数据都满足某个条件。例如,需要确定某个产品是否没有货了(库存为0)。
Linq提供了两个布尔方法:Any() 和 All(),它们可以快速确定对于数据而言,某个条件是true还是false。如下面示例所示:
bool anyStu = list.Any(stu => stu.Sex == "男"); if (anyStu) { Console.WriteLine("学员中有男同学"); } else { Console.WriteLine("学员中没有男同学"); } bool allStu = list.All(stu => stu.Sex == "男"); if (allStu) { Console.WriteLine("学员中全部是男同学"); } else { Console.WriteLine("学员中不全是男同学"); } |
2.2.4 ThenBy -----多级排序
使用方法语法进行多级排序时,后台的操作比较复杂,它使用了ThenBy()和OrderBy()方法。示例代码如下:
var result=list.OrderBy(stu=>stu.Class) .ThenBy(stu=>stu.Age) .ThenBy(stu=>stu.Name) .Select(stu=>new {stu.Name,stu.Age,stu.Class}); |
如果第一个字段是以降序排序,需要使用OrderByDescending()方法,其他字段降序排序需要使用ThenByDescending()方法。
2.2.5 Take和Skip
Take()方法对应SQL语句中的Top运算符。
与Take()方法相反的是Skip()方法,它可以跳过前n个结果,返回剩余的结果。
Take()和Skip()在Linq中成为分区运算符。
var result = list.OrderBy(stu => stu.Age); Console.WriteLine("年龄最小的两名学员是:"); foreach (var stu in result.Take(2)) { Console.WriteLine(stu); } Console.WriteLine("其他学员依次为:"); foreach (var stu in result.Skip(2)) { Console.WriteLine(stu); } |
2.2.6 First和FirstOrDefault
First()方法用来查找集合中第一个匹配的元素,如果没有找到匹配的结果则会引发一个异常。可以使用FirstOrDefault()方法避免异常的发生。
示例代码:
Console.WriteLine("姓名为lisi的同学信息:"); Console.WriteLine(list.First(stu => stu.Name == "lisi")); Console.WriteLine("姓名为hanjiu的同学信息:"); Console.WriteLine(list.FirstOrDefault(stu => stu.Name == "hanjiu")); |
2.2.7 集运算符
Linq提供了标准的集运算符,如Union()和Intersect(),对查询结果执行操作,上一章的Distinct()也是一个集运算符。
下面定义一个分数类
class Score
{
public int ID{get;set;}
public int score{get;set;}
}
示例代码:
static void Main(string[] args) { List<Student> list = new List<Student>{ new Student{ID=1,Name="zhangsan",Sex="男", Age=18,Class=50}, new Student{ID=2,Name="lisi",Sex="男", Age=18,Class=50}, new Student{ID=3,Name="wuangwu",Sex="男", Age=20,Class=51}, new Student{ID=4,Name="zhaoliu",Sex="男", Age=20,Class=52}, new Student{ID=5,Name="zhouqi",Sex="女", Age=21,Class=52}, new Student{ID=6,Name="wangba",Sex="女", Age=20,Class=52} }; List<Score> Scores = new List<Score> { new Score {ID=1,score=80}, new Score {ID=2,score=90}, new Score {ID=3,score=70}, new Score {ID=4,score=60}, new Score {ID=5,score=50}, new Score {ID=7,score=40}}; var student = from s in list select s.ID; var score = from scr in Scores select scr.ID; var stuWithScore = student.Intersect(score); Console.WriteLine("有成绩的学员编号为:"); foreach (var item in stuWithScore) { Console.WriteLine(item); } Console.WriteLine("未知学员的成绩编号为:"); var scoreNoStu = score.Except(student); foreach (var item in scoreNoStu) { Console.WriteLine(item); } Console.WriteLine("所有的编号为:"); var allID = score.Union(student); foreach (var item in allID) { Console.WriteLine(item); } } |
Intersect() 查找在Student结果中有成绩的学员编号,
Except()用于查找没有匹配学员的成绩编号
Union()预算法用于查找两个结果的并集,要删除重复项
集运算符要求集成员有相同的类型才能确保得到希望的结果。
2.2.8 Join查询
Join可以用一个查询搜索两个列表中相关的数据,用关键字段把结果连接起来。类似于SQL中join(内连接)操作。如:
var result = from stu in list join scr in Scores on stu.ID equals scr.ID select new { stu.ID, stu.Name, scr.score }; foreach (var ss in result) { Console.WriteLine(ss); } |
相关文章推荐
- Linq系列—简介
- linq简介
- linq 1 - linq简介
- LINQ学习心得分享--------(一)LINQ简介和基础学习
- [.net]LINQ体验(1)——LINQ简介和LINQ语句之Where(转)
- LINQ新特性简介及入门教程
- LINQ体验(4)——LINQ简介和LINQ to SQL语句之Where
- Linq系列教程三(入门之查询简介)
- C# Linq简介
- LINQ体验(4)——LINQ简介和LINQ to SQL语句之Where
- 微软免费图书《Introducing Microsoft LINQ》翻译--版权声明及本书简介
- .Net开发必备十大工具详解之查询表达式(LINQ)简介
- LINQ新特性简介及入门教程
- LINQ体验(4)——LINQ简介和LINQ to SQL语句之Where
- LINQ简介及其优点
- LINQ技术简介(一)var、lambda表达式
- LINQ 查询简介 (C#)
- System.Xml.Linq简介
- LINQ(一)查询简介
- Linq 简介