第7章:Linq
本章目标
- 掌握Linq的运用
本章内容
Linq概述
什么是Linq
Lanaguage Interated Query(语言集成查询),Linq 是集成C# 和VB这些语言中用于提供数据查询能力的一个新特性。Linq用于以对象形式管理关系数据,并提供了丰富的查询功能。
LINQ是一组语言特性和API,使得你可以使用统一的方式编写各种查询。用于保存和检索来自不同数据源的数据,从而消除了编程语言和数据库之间的不匹配,以及为不同类型的数据源提供单个查询接口。
LINQ总是使用对象,因此你可以使用相同的查询语法来查询和转换XML、对象集合、SQL数据库、ADO.NET数据集以及任何其他可用的LINQ提供程序格式的数据。
LInq支持的数据源
- LINQ to Objects 主要负责对象的查询。
- LINQ to XML 主要负责XML的查询。
- LINQ to ADO.NET 主要负责数据库的查询。
- LINQ to SQL
- LINQ to DataSet
- LINQ to Entities
Linq的优势
1、熟悉的语言:开发人员不必为每种类型的数据源或数据格式学习新的语言。
2、更少的编码:相比较传统的方式,LINQ减少了要编写的代码量。
3、可读性强:LINQ增加了代码的可读性,因此其他开发人员可以很轻松地理解和维护。
4、标准化的查询方式:可以使用相同的LINQ语法查询多个数据源。
5、类型检查:程序会在编译的时候提供类型检查。
6、智能感知提示:LINQ为通用集合提供智能感知提示。
7、整形数据:LINQ可以检索不同形状的数据。
匿名类型
-
匿名类型是可以创建无名类型的一种类型,经常用于LINQ查询的结果中。
-
匿名类型只能和局部变量配合使用,不能用于类成员。
-
匿名类型没有名字,必须使用var关键字作为变量类型。
-
编译器为匿名对象创建的属性是只读的,所以不能设置匿名类型对象的属性。
-
格式:
static void Fun1() { var man = new { Name="孙悟空", Age = 25, Sex='男' }; Console.WriteLine("姓名:{0}, 年龄:{1}, 性别:{2}", man.Name, man.Age, man.Sex); }
方法语法和查询语法
初识查询语法和方法语法
-
我们使用LINQ查询时可以使用两种形式的语法:方法语法和查询语法。
-
方法语法:使用标准的方法调用,这些方法是一组叫做标准查询运算符的方法。方法语法命令式的,指明了查询方法调用的顺序。
-
查询语法:类似于SQL语句,使用查询表达式形式书写。查询语法是声明式的,查询描述的是你想返回的东西,但并没有指明如何执行这个查询。
static void Fun2() { int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //查询语法 IEnumerable<int> result1 = from n in nums where n > 4 && n < 8 select n; //方法语法 IEnumerable<int> result2 = nums.Where(x => (x > 4 && x < 8));//返回枚举 //两种形式的组合 int count = (from n in nums where n > 4 && n < 8 select n).Count();//返回单个值 //查看结果 foreach (int i in result1) Console.Write(i); Console.WriteLine(); foreach (int i in result2) Console.Write(i); Console.WriteLine(); Console.Write(count); }
查询变量
-
LINQ查询可以返回两种类型的结果,如下:
-
枚举:包含了一组数据
-
标量:一个单一的值
-
-
理解查询变量:
- 如果查询表达式返回枚举,查询一直到处理枚举时才会执行。(延迟执行)
- 如果枚举被处理多次,查询就会执行多次。
- 如果在进行遍历之后,查询执行之前数据有改动,则查询会使用新的数据。
- 如果查询表达式返回标量,查询立即执行,并把结果保存在查询变量中。
查询表达式的结构
查询表达式由查询体后的from子句组成。
- 子句必须按照一定的顺序。
- from子句和select…group这两部分是必需的。
- 其他子句是可选的。
- 可以有任意多的from…let…where子句。
from子句
-
from子句和foreach子句格式十分相似,但实际有很大区别:
- foreach语句命令式指定了按顺序一个个访问集合中的项。from子句只是声明式地规定集合中的每个项都要访问,并没有指定顺序。
- foreach在遇到代码时就执行其主体。from子句什么也不执行,只有在遇到访问查询变量的语句时才会执行。
-
格式:
-
代码示例:
static void Fun3() { int[] ints = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; var nums = from n in ints where n > 7 //使用迭代变量n select n; //使用迭代变量n foreach (var n in nums) Console.WriteLine(n); }
join子句
-
注意事项:
- 使用联结来结合两个或更多集合中的数据。
- 联结对象接受两个集合,然后创建一个临时的对象集合,每一个对象包含原始集合对象中的所有字段。
- 字段只能使用equals比较,不能使用==
-
格式:
-
代码示例:
/// <summary> /// 学生 /// </summary> class Student { /// <summary> /// 学号 /// </summary> public string StudentNo { get; set; } /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 性别 /// </summary> public char Sex { get; set; } } /// <summary> /// 成绩 /// </summary> class Result { /// <summary> /// 学号 /// </summary> public string StudentNo { get; set; } /// <summary> /// 科目 /// </summary> public string Subject { get; set; } /// <summary> /// 分数 /// </summary> public int Score { get; set; } }
static void Fun4() { //学生 Student[] students = new Student[] { new Student { StudentNo="GCKJ001", Name="曾令耀", Age=18,Sex='男' }, new Student { StudentNo="GCKJ002", Name="李尚驰", Age=18,Sex='男' }, new Student { StudentNo="GCKJ003", Name="黄朗云", Age=18,Sex='女' } }; //成绩