《Illustrated C# 2012, 4th Edition》Daniel M. Solis 第19章 LINQ 笔记

LINQ概述

LINQ,读作link,语言集成查询(Language Integrated Query)。
对一种数据源类型实现LINQ查询的代码模块,称为LINQ提供程序(provider)。

匿名类型(anonymous type)的语法:

匿名类型只能在函数体中使用。
匿名类型的成员是只读的,无法修改。
如果将匿名类型对象赋值给一个变量,则这个变量只能使用var声明。

匿名类型的成员初始化语句有三种形式:赋值形式、成员访问表达式、标识符:

在赋值形式中,赋值运算符两边的标识符允许重名。

var student = new {Age = Age, Name = Other.Name, Major = Major};

如果编译器遇到相同的匿名类型(参数名、推断类型、排列顺序都相同),会复用这个类型,不会创建新的类型。

LINQ查询有两种形式的语法:方法语法(method syntax)和查询语法(query synatx)。
方法语法使用标准的方法调用。方法语法是命令式(imperative)的,指明查询方法调用的顺序。
查询语法和SQL语句相似。查询语法是声明式(declarative)的,只描述要返回的东西。
查询语法在编译时,被编译器翻译为方法调用,因此两者性能上没有差异。但方法语法还提供了一些查询语法没有的功能。

LINQ查询返回的结果称为查询变量,查询变量有两种:可枚举类型(IEnumerable<T>)和标量(scalar),支持var关键字由编译器推断。
可枚举类型的查询变量:

  1. 访问查询变量时,才进行查询。每次访问都重新查询
  2. 查询之前,如果数据有更新,查询会使用最新的数据。

标量的查询变量,立即查询并保存查询结果。

查询表达式

查询表达式的结构:

from子句的语法:

from Type Item in Items
  • Type是元素类型。Type是可选的,编译器可以自行推断。
  • Item是迭代变量
  • Items是要查询的集合,必须是可枚举类型。

与foreach语句不同,from子句不指定集合中的项出现的顺序。

from子句示例:

from子句可以同时存在多个:

from子句,可以后跟任意个join子句:

join子句的语法:

join Identifier in Collection2 on Field1 equals Field2
  • 注意:使用equals关键字,而不是==。

join子句用于联结多个集合,创建一个临时的新集合。

let子句可以声明一个变量,语法如下:

let Identifier = Expression

let子句示例:

where子句可以筛选集合中的项,语法如下:

where BooleanExpression

where子句示例:

orderby子句用于排序,默认为升序,可以使用ascending和descending关键字显式设置为升序和降序,语法如下:

orderby子句示例:

select...group子句由select子句和group...by子句组成,其中group...by子句是可选的。select子句用于拣选结果,group...by子句用于分组,语法如下:

select Expression
group Expression1 by Expression2

select子句与匿名类型数组示例:

group...by子句示例:

group...by子依据键(key)分组,返回集合的集合:

into子句可以延续查询,为查询的一部分结果赋予一个名字,在查询的另一部分中使用,语法如下:

into子句示例:

标准查询运算符

标准查询运算符是系列API,被查询的对象必须实现IEnumerable<T>接口,称为序列。

标准查询运算符共47个:

标准查询运算符在System.Linq.Enumerable类中声明,是IEnumerable<T>泛型类的扩展方法。

查询表达式与标准查询运算符可以组合使用:

标准查询运算符中的一些还支持接受泛型委托作为参数:

LINQ还预定了两套泛型委托类型:Func委托和Action委托,各有17个成员,作为标准查询运算符参数的泛型委托类型。

LINQ to XML

标记标签不是文档的数量,是关于数据的数据,称为元数据。

元素是XML的基本要素,元素通过标签划分,元素的数据在开始和关闭标签之间。

XML的标签有两种形式:

XML是树状结构,必须有一个根元素。
与HTML不同,XML的标签区分大小写。
XML的特性是键/值对,值必须包含在引号内(单引号、双引号均可)。
与HTML不同,XML中多个空间不会合并为一个空格。

LINQ to XML提供了一些类,其中最重要的是XElement、XAttribute和XDocument:

图中的类除了XAttribute以外,都从XNode类继承。

创建、保存、加载、打印XML示例:

查询XML的方法:

查询XML示例:

操作XML的方法:

操作XML示例:

在XElement构造函数中包含XAttribute构造函数可以添加特性。
XAttribute构造函数有两种形式,一种是接受name和value,另一种是接受XAttribute的引用。
在XElement节点调用Attribute()方法,传递特性名可以获取特性。
XAttribute类的Remove()方法可以移除特性。
在XElement节点,调用SetAttributeValue()方法,将某个特性的值设置为null,同样可以移除这个特性。SetAttributeValue()方法还可以改变一个特性的值。

XComment节点是注释。
XDeclaration节点是XML的声明,包含XML版本号、字符编码和是否依赖外部引用。
XProcessingInstruction用于提供XML如何被使用和翻译的额外数据,如关联一个样式表。
XComment、XDeclaration、XProcessingInstruction使用示例:

LINQ查询XML示例如下: