[深入学习C#]LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询
[深入学习C#]LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询
简介
[在Git上下载源码](https://github.com/honantic/LINQ-Query.git)
在工程中我们少不了要定义类或者结构去储存数据,这些数据将被临时地储存在内存中,现在我们想要对其完成一些类似于查找、过滤等等常见的任务的时候,我们该如何去做呢?
我们可以自己写代码去对集合中的每个对象进行遍历,检查变量的每个字段看其是否满足条件。这样的故事已经发生太多次了,微软怎么可能容忍在C#里发生如此弱智的事情呢?于是,C#的设计者决定在C#中集成查询的语法,以最大限度地减少程序员书写类似代码的情况。
这也就是我们说的LINQ(Language Intergated Query) 也就是语言集成查询,我们可以使用同样的语法访问不同的数据源。
为什么要使用LINQ?
几乎所有的应用程序都需要对数据进行处理,大部分的程序都通过自定义的逻辑来完成这些操作。这样做的弊端之意就是,代码逻辑将会跟它处理的数据的结构紧密耦合在一起,如果数据结构发生了改变,也许将会带来海量的代码改动。
为了解决这个问题,C#将这些处理数据的代码都抽象出来,提供给了广大开发者。这就是LINQ。
LINQ的语法类似于关系和分层查询语言(SQL和XQuery),我们可以在不更改查询代码的情况下对数据结构进行更改。LINQ比之SQL要更加灵活,可以处理更广泛的逻辑数据结构。当然,这些数据结构都需要实现了IEnumerable或者IEnumerable< T >接口,才可以进行LINQ查询。
LINQ查询表达式语法详解
表达式基础语法
LINQ查询表达式以from子句开始,以select或者group子句结束。在这两个子句之间可以跟零个或者多个from、let、where、join或者orderby子句。
每个from子句都是一个生成器,该生成器将引入一个包括序列(Sequence)的元素的范围变量(range variable)。每个let子句都会引入一个范围变量,以表示通过前一个范围变量计算的值。每个where子句都是一个筛选器,用于从结果中排除项。每个join子句都将指定的源序列键与其他序列的键进行比较,以产生匹配对。每个orderby子句都会根据指定的条件对各项进行重新排序。而最后的select或者group子句根据范围变量来指定结果的表现形式。最后可以使用into子句来连接查询,将某一查询结果的视为后续查询的生成器。
标准查询操作符
在了解LINQ查询表达式之前,怎么能不了解下它的查询操作符呢?下面列表列出了LINQ定义的标准查询操作符。
表1:LINQ标准查询操作符
标准查询操作符 | 说明 |
---|---|
where OfType | 筛选操作符定义了返回元素的条件。在Where查询操作符中,可以使用谓词,例如Lambda表达式定义的谓词,来返回布尔值。OfType根据类型筛选元素,只返回TResult的类型元素 |
Select 和SelectMany | 投射操作符用于把对象转换为另一个类型的新对象。Select和SelectMany定义了根据选择器函数选择结果值的投射。 |
OrderBy、ThenBy 、OrderByDescending 、ThenByDescending 、Reverse | 排序操作符改变所返回的元素的顺序。OrderBy按升序排列,OrderByDescending按降序排列。如果第一次排序结果很类似,就可以使用ThenBy和ThenByDescending操作符进行第二次排序。Reverse反转集合中的元素顺序。 |
GroupBy、ToLookUp | 组合运算符把数据放在组里面。GroupBy操作符组合有公共键的元素。ToLookUp通过创建一个一对多的字典,来组合元素。 |
Join、GroupJoin | 链接运算符用于合并不直接相关的集合。使用Join操作符,可以根绝键选择器函数连接两个集合,这类似于SQL中的Join。GroupJoin操作符连接两个集合,组合其结果。 |
Any、All、Contains | 如果元素序列满足指定的条件,两次操作符就返回布尔值。Any、ALll和Contains都是限定符操作符。Any确定集合中是否有确定满足谓词函数的元素。ALll确定集合中的所有元素是否都满足谓词函数。Contains检查某个元素是否在集合中。这些操作符都返回一个布尔值。 |
Take、Skip、TakeWhile、SkipWhile | 分区操作符返回集合的一个子集,Take、Skip、TakeWhile、SkipWhile都是分区操作符。使用它们可以得到部分结果,使用Take必须指定要从集合中提取的元素个数;Skip跳过指定个数的元素,提取其它元素;TakeWhile提取条件为真的元素。 |
Distinct、Union、Intersect、Except、Zip | Set操作符返回一个集合。Distinct从集合中删除重复的元素,除了Distinct之外,其它的Set操作符都需要两个集合。Union返回出现在其中一个集合中的唯一元素。Intersect返回两个集合中都有的元素。Except返回值出现在一个集合中的元素。Zip是.NET 4新增的,它把两个集合合并为一个。 |
First、FirstOrDefault、Last、LastOrDefault、ElementAt、ElementAtOrDefault、Single、SingleOrDefault | 这些元素操作符仅返回一个元素。First返回第一个满足条件的元素。FirstOrDefault类似于First,单如果没有找到满足条件的元素,就返回类型的默认值。Last返回最后一个满足条件的元素。ElementAt指定了要返回的元素的位置。Single只返回一个满足条件的元素。如果有多个元素都满足条件,就抛出一个异常。 |
Count、Sum、Min、Max、Average、Aggregate | 聚合操作符计算集合的一个值。利用这些聚合操作符,可以计算所有值的总和、所有元素的个数、值最大和最小的元素,以及平均值等等。 |
ToArray、ToEnumerable、ToList、ToDictionary、Cast | 这些转换操作符将集合转换为数组:IEnumerable、IList、IDictionary等。 |
Empty、Range、Repeat | 这些生成操作符返回一个心机和。使用Empty时集合是空的;Range返回一系列数字;Repeat返回一个始终重复一个值的集合。 |