LINQLINQ

走进 LINQ 的世界

走进 LINQ 的世界

  在此之前曾刊登了三首关于 LINQ 的随笔:

    进阶:《LINQ
标准查询操作概述》(强烈推荐)

    技巧:《Linq To Objects –
如何操作字符串》 和
《Linq To Objects –
如何操作文件目录》

  现在,自己打算再整理一篇有关 LINQ 入门的随笔,也是声泪俱下的哦。

 

  在此之前曾刊登过三篇有关 LINQ 的随笔:

    进阶:《LINQ
标准查询操作概述》(强烈推荐)

    技巧:《Linq To Objects –
如何操作字符串》 和
《Linq To Objects –
如何操作文件目录》

  现在,自己打算再整理一首关于 LINQ 入门的随笔,也是活泼的啊。

 

目录

  • LINQ 简介
  • 介绍 LINQ
    查询
  • LINQ
    基本查询操作
  • 应用 LINQ
    进行多少易
  • LINQ
    查询操作的类型涉及
  • LINQ
    中的查询语法和方法语法

 

目录

  • LINQ 简介
  • 介绍 LINQ
    查询
  • LINQ
    基本查询操作
  • 动用 LINQ
    进行数据易
  • LINQ
    查询操作的花色涉及
  • LINQ
    中的查询语法和道语法

 

LINQ 简介

  语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5
版中引入的如出一辙起创新意义。

  传统上,针对数据的询问都是盖略的字符串表示,而从未编译时类型检查或
IntelliSense
支持。此外,您还得对以下各种数据源学习一栽不同之询问语言:SQL
数据库、XML 文档、各种 Web 服务等等。 通过LINQ,
您得应用语言关键字和熟悉的演算符针对强类型化对象集合编写查询。

图片 1

  

  以 Visual Studio 中,可以吗以下数据源编写 LINQ 查询:SQL Server
数据库、XML 文档、ADO.NET
数据集,以及支持 IEnumerable 或泛型 IEnumerable<T> 接口的擅自对象集合。

  使用要求:项目 ≥ .NET Framework 3.5 。

 

LINQ 简介

  语言集成查询 (LINQ) 是 Visual Studio 2008 和 .NET Framework 3.5
版中引入的等同码创新成效。

  传统上,针对数据的查询都是以略的字符串表示,而并未编译时类型检查或者
IntelliSense
支持。此外,您还须对以下各种数据源学习一种不同的查询语言:SQL
数据库、XML 文档、各种 Web 服务等等。 通过LINQ,
您可以应用语言关键字与习的运算符针对强类型化对象集合编写查询。

图片 2

  

  于 Visual Studio 中,可以啊以下数据源编写 LINQ 查询:SQL Server
数据库、XML 文档、ADO.NET
数据集,以及支持 IEnumerable 或泛型 IEnumerable<T> 接口的即兴对象集合。

  使用要求:项目 ≥ .NET Framework 3.5 。

 

一、介绍 LINQ 查询

  查询是一律种植于数据源检索数据的表达式。随着日的推迟,人们曾也各种数据源开发了不同的语言;例如,用于关系数据库的
SQL 和用来 XML 的
XQuery。因此,开发人员不得不对他们必须支持之每种数据源或数量格式而习新的查询语言。LINQ
通过提供平等栽跨数据源和数码格式使用数据的同样模型,简化了就等同情。在
LINQ 查询中,始终会为此到对象。可以用同样的编码模式来询问与换 XML
文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的多少与对其发出 LINQ
提供次可用之旁其他格式的数。  

 

一、介绍 LINQ 查询

  查询是相同种由数据源检索数据的表达式。随着时光之延,人们已也各种数据源开发了不同之言语;例如,用于关系数据库的
SQL 和用来 XML 的
XQuery。因此,开发人员不得不对他们必须支持的各级种数据源或数量格式而读新的查询语言。LINQ
通过提供平等种跨数据源和数据格式使用数据的等同模型,简化了这同一情。在
LINQ 查询中,始终会用到对象。可以动用同样之编码模式来查询与转换 XML
文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的数额和对那产生 LINQ
提供程序可用之另外其它格式的数量。  

 

  1.1 查询操作的老三单部分

  操作三统曲:①取多少源 ②创立查询 ③实践查询

图片 3图片 4

 1 internal class Program
 2 {
 3         private static void Main(string[] args)
 4         {
 5             //1.获取数据源
 6             var nums = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
 7 
 8             //2.创建查询
 9             var numQuery =
10                 from num in nums
11                 where (num % 2) == 0
12                 select num;
13 
14             //3.执行查询
15             foreach (var num in numQuery)
16             {
17                 Console.WriteLine("{0}", num);
18             }
19         }
20 }

View Code

图片 5

 

   下图展示了完全的询问操作。在 LINQ
中,查询的执行和查询自己截然不同;换句话说,查询本人指的凡独自开创查询变量,不搜任何数。

图片 6

  

  1.1 查询操作的老三个组成部分

  操作三部曲:①得到多少源 ②开立查询 ③尽查询

图片 7图片 8

 1 internal class Program
 2 {
 3         private static void Main(string[] args)
 4         {
 5             //1.获取数据源
 6             var nums = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
 7 
 8             //2.创建查询
 9             var numQuery =
10                 from num in nums
11                 where (num % 2) == 0
12                 select num;
13 
14             //3.执行查询
15             foreach (var num in numQuery)
16             {
17                 Console.WriteLine("{0}", num);
18             }
19         }
20 }

View Code

图片 9

 

   下图显示了整的查询操作。在 LINQ
中,查询的实践及查询本人截然不同;换句话说,查询自己指的是单创造查询变量,不找任何数。

图片 10

  

  1.2 数据源

  在上一个示范中,由于数据源是累组,因此它们隐式支持泛型 IEnumerable<T> 接口。支持 IEnumerable<T> 或派生接口(如泛型 IQueryable<T>)的品种称为可查询类型。  

  可查询类型不欲展开修改或者特别处理便可以就此作 LINQ
数据源。如果来数据还尚未作为可查询类型出现在内存中,则 LINQ
提供程序必须是方式意味着来数据。例如,LINQ to XML 将 XML
文档加载到但是查询的 XElement 类型中:

  //从 XML 中创建数据源
  //using System.Xml.Linq;
  var contacts = XElement.Load(@"c:\xxx.xml");

  

  于 LINQ to SQL 中,首先用创建对象关系映射。
针对这些目标编排查询,然后由 LINQ to SQL 在运行时处理和数据库的通信。

图片 11图片 12

1     var  db = new Northwnd(@"c:\northwnd.mdf");
2     
3     //查询在伦敦的客户
4     var custQuery =
5         from cust in db.Customers
6         where cust.City == "London"
7         select cust;

Customers 表示数据库中之特定表

 

  1.2 数据源

  于齐一个示范中,由于数据源是几度组,因此其隐式支持泛型 IEnumerable<T> 接口。支持 IEnumerable<T> 或派生接口(如泛型 IQueryable<T>)的种类称为可查询类型。  

  可查询类型不需要进行修改或者特殊处理便得据此作 LINQ
数据源。如果来数据还尚无作可查询类型出现在内存中,则 LINQ
提供程序必须是方法意味着来数据。例如,LINQ to XML 将 XML
文档加载到但是查询的 XElement 类型中:

  //从 XML 中创建数据源
  //using System.Xml.Linq;
  var contacts = XElement.Load(@"c:\xxx.xml");

  

  以 LINQ to SQL 中,首先需要创建对象关系映射。
针对这些目标编排查询,然后由 LINQ to SQL 在运作时处理与数据库的通信。

图片 13图片 14

1     var  db = new Northwnd(@"c:\northwnd.mdf");
2     
3     //查询在伦敦的客户
4     var custQuery =
5         from cust in db.Customers
6         where cust.City == "London"
7         select cust;

Customers 表示数据库中之特定表

 

  1.3 查询

  查询指定要打数量源中检索的信。
查询还好指定在回到这些信之前如何对其开展排序、分组和结构化。
查询存储于询问变量中,并因此查询表达式进行初始化。

  之前的示范中的询问是自整数数组中回到所有的偶数。
该查询表达式包含三个子句:fromwhere 和 select。(如果您熟悉
SQL,您会专注到这些子句的各个和 SQL
中之逐条相反。)from 子句指定数据源,where 子句子指定应用筛选器,select 子句指定返回的因素的档次。
目前亟需留意的凡,在 LINQ 中,查询变量本身不实施外操作以不回去外数。
它只是存储于后头有时刻执行查询时为变化结果如果必要的音讯。

 

  1.3 查询

  查询指定要起数额源中检索的信。
查询还好指定在回到这些消息之前如何对那个进行排序、分组和结构化。
查询存储于查询变量中,并因此查询表达式进行初始化。

  之前的示范中之询问是自整数数组中归所有的偶数。
该查询表达式包含三单子句:fromwhere 和 select。(如果您熟悉
SQL,您见面小心到这些子句的相继及 SQL
中之相继相反。)from 子句指定数据源,where 子句子指定应用筛选器,select 子句指定返回的因素的档次。
目前要留意的凡,在 LINQ 中,查询变量本身不履行另外操作而不回来外数据。
它只是存储在后来有时刻执行查询时也转结果一旦必要的音信。

 

  1.4 查询执行

  1.4 查询执行

  1.推执行

    如前所述,查询变量本身只是存储查询命令。  实际的询问执行会延迟到在 foreach 语词被循环访问查询变量时产生。
此概念叫“延迟执行”。

  1.延执行

    如前所述,查询变量本身只是存储查询命令。  实际的查询执行会延迟到在 foreach 语句子被循环访问查询变量时发。
此概念叫“延迟执行”。

  2.要挟立即施行

    对同多级源元素执行聚合函数的询问必须首先循环访问这些要素。CountMaxAverage 和 First 就属此类查询。由于查询本人要使用 foreach 以便回到结果,因此这些查询在实行时不利用显式 foreach 语句子。另外还要注意,这些品种的询问返回单个值,而非是 IEnumerable 集合。 

图片 15图片 16

1     var numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
2 
3     var evenNumQuery =
4         from num in numbers
5         where (num % 2) == 0
6         select num;
7 
8     var evenNumCount = evenNumQuery.Count();

View Code

图片 17

 

  若一旦强制立即执行任意查询并缓存其结果,可以调用 ToList<TSource> 或 ToArray<TSource> 方法。

图片 18图片 19

1     var numQuery2 =
2            (from num in numbers
3             where (num % 2) == 0
4             select num).ToList();
5 
6     var numQuery3 =
7           (from num in numbers
8            where (num % 2) == 0
9             select num).ToArray();

View Code

 

  此外,还足以经过当紧跟查询表达式之后的职放置一个 foreach 循环来强制执行查询。但是,通过调用 ToList 或 ToArray,也得以用拥有数据缓存在么集合对象中。 

 

  2.强制立即执行

    对平多元源元素执行聚合函数的询问必须首先循环访问这些因素。CountMaxAverage 和 First 就属此类查询。由于查询自己必须采用 foreach 以便回到结果,因此这些查询在履时莫以显式 foreach 语句。另外还要小心,这些项目的询问返回单个值,而未是 IEnumerable 集合。 

图片 20图片 21

1     var numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
2 
3     var evenNumQuery =
4         from num in numbers
5         where (num % 2) == 0
6         select num;
7 
8     var evenNumCount = evenNumQuery.Count();

View Code

图片 22

 

  若要强制立即施行任意查询并缓存其结果,可以调用 ToList<TSource> 或 ToArray<TSource> 方法。

图片 23图片 24

1     var numQuery2 =
2            (from num in numbers
3             where (num % 2) == 0
4             select num).ToList();
5 
6     var numQuery3 =
7           (from num in numbers
8            where (num % 2) == 0
9             select num).ToArray();

View Code

 

  此外,还得透过当紧跟查询表达式之后的职务放置一个 foreach 循环来强制执行查询。但是,通过调用 ToList 或 ToArray,也堪拿装有数据缓存在单个集合对象吃。 

 

第二、基本 LINQ 查询操作

次、基本 LINQ 查询操作

  2.1 获取数据源:from

  于 LINQ
查询中,第一步是指定数据源。像在大多数编程语言中一样,必须优先声明变量,才能够使用它。在
LINQ 查询中,最先祭 from 子词的目的是引入数据源和界定变量。

图片 25图片 26

1     //queryAllCustomers 是 IEnumerable<Cutsomer> 类型
2     //数据源 (customers) 和范围变量 (cust)
3     var queryAllCustomers = from cust in customers
4                                            select cust;

View Code

  范围变量类似于 foreach 循环中的迭代变量,但以询问表达式中,实际上不起迭代。执行查询时,范围变量将就此拿 customers 中的每个后续元素的援。因为编译器可以推断 cust 的品类,所以若不用显式指定此类型。

 

  2.1 获取数据源:from

  以 LINQ
查询中,第一步是点名数据源。像于大部分编程语言中平等,必须事先声明变量,才会使它们。在
LINQ 查询中,最先祭 from 子句子之目的是引入数据源和限变量。

图片 27图片 28

1     //queryAllCustomers 是 IEnumerable<Cutsomer> 类型
2     //数据源 (customers) 和范围变量 (cust)
3     var queryAllCustomers = from cust in customers
4                                            select cust;

View Code

  范围变量类似于 foreach 循环中之迭代变量,但当查询表达式中,实际上不生迭代。执行查询时,范围变量将因此拿 customers 中之每个后续元素的援。因为编译器可以想见 cust 的品种,所以你不要显式指定此类型。

 

  2.2 筛选:where

  也许不过常用之询问操作是下布尔表达式形式的筛选器。此筛选器使查询才回那些表达式结果吗
true 的因素。使用 where 子句子生成结果。实际上,筛选器指定从源序列中祛哪些要素。

图片 29图片 30

1     var queryLondonCustomers = from cust in customers
2                                   where cust.City = "London"
3                                     select cust;

单单回去地址位于伦敦的 customers。

  您得应用深谙的 C#
逻辑 AND(&&)和 OR(||) 运算符来根据需要以 where 子句被使用任意数量的淘表达式。 

图片 31图片 32

where cust.City = "London" && cust.Name = "Devon"

若是要就回去位于“伦敦”和人名也“Devon”的客户

图片 33图片 34

where cust.City = "London" || cust.Name = "Paris"

万一要回位于伦敦还是巴黎之客户

 

  2.2 筛选:where

  也许不过常用的查询操作是采用布尔表达式形式之筛选器。此筛选器使查询才回去那些表达式结果为
true 的素。使用 where 子句生成结果。实际上,筛选器指定从源序列中排除哪些因素。

图片 35图片 36

1     var queryLondonCustomers = from cust in customers
2                                   where cust.City = "London"
3                                     select cust;

仅回去地址在伦敦之 customers。

  您可以深谙的 C#
逻辑 AND(&&)和 OR(||) 运算符来根据需要以 where 子句被使任意数量之筛选表达式。 

图片 37图片 38

where cust.City = "London" && cust.Name = "Devon"

假若使才回位于“伦敦”和姓名为“Devon”的客户

图片 39图片 40

where cust.City = "London" || cust.Name = "Paris"

假如要回位于伦敦要么巴黎之客户

 

  2.3 排序:orderby

  通常可以好有益于地拿回来的数目进行排序。orderby 子句以使返回的队中之要素以让排序的色的默认比较器进行排序。

图片 41图片 42

1     var queryLondonCustomers = from cust in customers
2                                where cust.City = "London"
3                                orderby cust.Name descending 
4                                select cust;

比如 Name 属性对结果开展排序

  因为 Name 是一个字符串,所以默认比较器执行打 A 到 Z
的假名排序。若使按倒顺序(从 Z 到 A)对结果开展排序,请动 orderby…descending 子句。

 

  2.3 排序:orderby

  通常可以十分有益地将返回的数量进行排序。orderby 子句子以设返回的排中的素以让排序的花色的默认比较器进行排序。

图片 43图片 44

1     var queryLondonCustomers = from cust in customers
2                                where cust.City = "London"
3                                orderby cust.Name descending 
4                                select cust;

论 Name 属性对结果开展排序

  因为 Name 是一个字符串,所以默认比较器执行打 A 到 Z
的假名排序。若一旦按部就班倒顺序(从 Z 到 A)对结果开展排序,请以 orderby…descending 子句。

 

  2.4 分组:group

  使用 group 子句,您可以以指定的键分组结果。

图片 45图片 46

 1     var queryLondonCustomers = from cust in customers
 2                     group cust by cust.City;
 3 
 4     foreach (var queryLondonCustomer in queryLondonCustomers)
 5     {
 6        Console.WriteLine(queryLondonCustomer.Key);
 7        foreach (var cust in queryLondonCustomer)
 8        {
 9           Console.WriteLine(cust.Name);
10        }
11     }

君可指定结果应随 City
分组,以便在伦敦或者巴黎的具备客户在各自组中。

  以本例中,cust.City 是键。

  在使用 group 子句子结束查询时,结果运用列表的列表形式。列表中之每个元素是一个具有 Key 成员和根据该键分组的因素列表的对象。在循环访问生成组序列的查询时,您得动嵌套的 foreach 循环。外部循环用于循环访问每个组,内部循环用于循环访问每个组的积极分子。
 

  如果您要引用组操作的结果,可以行使 into 关键字来创造而进一步查询的标识符。

图片 47图片 48

1     //custQuery 是 IEnumable<IGrouping<string, Customer>> 类型
2     var custQuery = from cust in customers
3                     group cust by cust.City
4                     into custGroup
5                     where custGroup.Count() > 2
6                     orderby custGroup.Key
7                     select custGroup;

此地的查询才回去那些带有两只以上之客户之组。

 

  2.4 分组:group

  使用 group 子词,您可随指定的键分组结果。

图片 49图片 50

 1     var queryLondonCustomers = from cust in customers
 2                     group cust by cust.City;
 3 
 4     foreach (var queryLondonCustomer in queryLondonCustomers)
 5     {
 6        Console.WriteLine(queryLondonCustomer.Key);
 7        foreach (var cust in queryLondonCustomer)
 8        {
 9           Console.WriteLine(cust.Name);
10        }
11     }

君得指定结果应按 City
分组,以便在伦敦抑或巴黎的享有客户在各自组中。

  于本例中,cust.City 是键。

  在使用 group 子句结束查询时,结果以列表的列表形式。列表中之每个元素是一个具 Key 成员及基于该键分组的素列表的靶子。在循环访问生成组序列的查询时,您要运用嵌套的 foreach 循环。外部循环用于循环访问每个组,内部循环用于循环访问每个组的积极分子。
 

  如果你必须引用组操作的结果,可以用 into 关键字来创造而更询问的标识符。

图片 51图片 52

1     //custQuery 是 IEnumable<IGrouping<string, Customer>> 类型
2     var custQuery = from cust in customers
3                     group cust by cust.City
4                     into custGroup
5                     where custGroup.Count() > 2
6                     orderby custGroup.Key
7                     select custGroup;

此处的查询才回那些富含两个以上的客户的组。

 

  2.5 联接:join

  联接运算创建数量源中没有显式建模的班中的涉。例如,您得履属来搜寻在同一地方的所有客户和经销商。在
LINQ 中,join 子句始终对对象集合而无直接指向数据库表运行。  

图片 53图片 54

1     var innerJoinQuery = from cust in customers
2                        join dist in distributors on cust.City equals dist.City
3                        select new {CustomerName = cust.Name, DistributorName = dist.Name};

譬如,您得履属来搜寻在同一地方的有所客户和经销商。

  在 LINQ 中,join 子句子始终对对象集合而未直接指向数据库表运行。
 

  于 LINQ 中,您不用像于 SQL 中那么往往利用 join,因为 LINQ
中之外键在目标模型中代表为涵盖项集合的特性。

图片 55图片 56

    from order in Customer.Orders...

比如说,Customer 对象涵盖 Order
对象的汇聚。不必执行属,只待使用点表示法访问订单。

  

  2.5 联接:join

  联接运算创建数量源中没有显式建模的班中的涉。例如,您得履属来探寻在同一地方的有客户和经销商。在
LINQ 中,join 子句始终本着对象集合而非直接针对数据库表运行。  

图片 57图片 58

1     var innerJoinQuery = from cust in customers
2                        join dist in distributors on cust.City equals dist.City
3                        select new {CustomerName = cust.Name, DistributorName = dist.Name};

譬如,您可尽属来查找在同地点的富有客户和经销商。

  在 LINQ 中,join 子词始终本着对象集合而无直接针对数据库表运行。
 

  于 LINQ 中,您不要像以 SQL 中那么频繁使用 join,因为 LINQ
中之外键在靶模型中代表为涵盖项集合的属性。

图片 59图片 60

    from order in Customer.Orders...

比如说,Customer 对象涵盖 Order
对象的集聚。不必执行属,只需要使用点表示法访问订单。

  

  2.6 选择(投影):select

  select 子词生成查询结果连指定每个返回的素的“形状”或项目。

  例如,您可以指定结果包含的是整套 Customer 对象、仅一个成员、成员的子集,还是有因计算还是新对象创建的一点一滴不同的结果类型。当 select 子句生成除源元素副本以外的情节常常,该操作称为“投影”。

 

  2.6 选择(投影):select

  select 子句生成查询结果连点名每个返回的要素的“形状”或项目。

  例如,您可指定结果包含的凡任何 Customer 对象、仅一个分子、成员的子集,还是有因计算还是新目标创建的全两样的结果类型。当 select 子句子生成除源元素副本以外的情时,该操作称为“投影”。

 

老三、使用 LINQ 进行多少易

  语言集成查询 (LINQ)
不仅可用于检索数据,而且还是一个功能强大的数目易工具。通过使用 LINQ
查询,您可将自序列用作输入,并应用多种办法修改其为创办新的输出序列。您可经过排序和分组来修改该队,而不用修改元素本身。但是,LINQ
查询的顶有力的功效是会创立新品类。这同样效果于 select 子句被落实。 例如,可以实施下列职责:  

  

老三、使用 LINQ 进行多少易

  语言集成查询 (LINQ)
不仅可用于检索数据,而且还是一个功能强大的数额易工具。通过以 LINQ
查询,您可以拿自序列用作输入,并下多种道修改其坐创建新的输出序列。您可以由此排序和分组来修改该队,而毋庸修改元素本身。但是,LINQ
查询的尽强大的功力是能够创立新类型。这同样作用于 select 子句被实现。 例如,可以实施下列职责:  

  

  3.1 将大半只输入联接到一个输出序列

图片 61图片 62

 1     class Student
 2     {
 3         public string Name { get; set; }
 4 
 5         public int Age { get; set; }
 6 
 7         public string City { get; set; }
 8 
 9         public List<int> Scores { get; set; }
10     }
11 
12     class Teacher
13     {
14         public int Id { get; set; }
15 
16         public string Name { get; set; }
17 
18         public int Age { get; set; }
19 
20         public string City { get; set; }
21 
22     }

学生及老师两个像样

图片 63图片 64

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             //创建第一个数据源
 6             var students = new List<Student>()
 7             {
 8                 new Student()
 9                 {
10                     Age = 23,
11                     City = "广州",
12                     Name = "小C",
13                     Scores = new List<int>(){85,88,83,97}
14                 },
15                 new Student()
16                 {
17                     Age = 18,
18                     City = "广西",
19                     Name = "小明",
20                     Scores = new List<int>(){86,78,85,90}
21                 },
22                 new Student()
23                 {
24                     Age = 33,
25                     City = "梦里",
26                     Name = "小叁",
27                     Scores = new List<int>(){86,68,73,97}
28                 }
29             };
30 
31             //创建第二个数据源
32             var teachers = new List<Teacher>()
33             {
34                 new Teacher()
35                 {
36                     Age = 35,
37                     City = "梦里",
38                     Name = "啵哆"
39                 },
40                 new Teacher()
41                 {
42                     Age = 28,
43                     City = "云南",
44                     Name = "小红"
45                 },
46                 new Teacher()
47                 {
48                     Age = 38,
49                     City = "河南",
50                     Name = "丽丽"
51                 }
52             };
53 
54             //创建查询
55             var peopleInDreams = (from student in students
56                             where student.City == "梦里"
57                             select student.Name)
58                             .Concat(from teacher in teachers
59                                     where teacher.City == "梦里"
60                                     select teacher.Name);
61 
62             //执行查询
63             foreach (var person in peopleInDreams)
64             {
65                 Console.WriteLine(person);
66             }
67 
68             Console.Read();
69         }
70     }

支配高出口代码。   

 

  3.1 将大半只输入联接到一个输出序列

图片 65图片 66

 1     class Student
 2     {
 3         public string Name { get; set; }
 4 
 5         public int Age { get; set; }
 6 
 7         public string City { get; set; }
 8 
 9         public List<int> Scores { get; set; }
10     }
11 
12     class Teacher
13     {
14         public int Id { get; set; }
15 
16         public string Name { get; set; }
17 
18         public int Age { get; set; }
19 
20         public string City { get; set; }
21 
22     }

学员及教职工两个像样

图片 67图片 68

 1     internal class Program
 2     {
 3         private static void Main(string[] args)
 4         {
 5             //创建第一个数据源
 6             var students = new List<Student>()
 7             {
 8                 new Student()
 9                 {
10                     Age = 23,
11                     City = "广州",
12                     Name = "小C",
13                     Scores = new List<int>(){85,88,83,97}
14                 },
15                 new Student()
16                 {
17                     Age = 18,
18                     City = "广西",
19                     Name = "小明",
20                     Scores = new List<int>(){86,78,85,90}
21                 },
22                 new Student()
23                 {
24                     Age = 33,
25                     City = "梦里",
26                     Name = "小叁",
27                     Scores = new List<int>(){86,68,73,97}
28                 }
29             };
30 
31             //创建第二个数据源
32             var teachers = new List<Teacher>()
33             {
34                 new Teacher()
35                 {
36                     Age = 35,
37                     City = "梦里",
38                     Name = "啵哆"
39                 },
40                 new Teacher()
41                 {
42                     Age = 28,
43                     City = "云南",
44                     Name = "小红"
45                 },
46                 new Teacher()
47                 {
48                     Age = 38,
49                     City = "河南",
50                     Name = "丽丽"
51                 }
52             };
53 
54             //创建查询
55             var peopleInDreams = (from student in students
56                             where student.City == "梦里"
57                             select student.Name)
58                             .Concat(from teacher in teachers
59                                     where teacher.City == "梦里"
60                                     select teacher.Name);
61 
62             //执行查询
63             foreach (var person in peopleInDreams)
64             {
65                 Console.WriteLine(person);
66             }
67 
68             Console.Read();
69         }
70     }

支配高出口代码。   

 

  3.2 选择各个源元素的子集

  1. 要要独自选源元素的一个分子,请以点运算。

1     var query = from cust in Customers
2                     select cust.City;

  

  2. 一旦要创造包含源元素的差不多个属性之素,可以用具有命名对象或匿名类型的对象初始值设定项。

1     var query = from cust in Customer
2                    select new {Name = cust.Name, City = cust.City};

 

  3.2 选择各个源元素的子集

  1. 要是要就选择源元素的一个分子,请以点运算。

1     var query = from cust in Customers
2                     select cust.City;

  

  2. 如要创包含源元素的大多单特性的因素,可以运用具有命名对象要匿名类型的对象初始值设定项。

1     var query = from cust in Customer
2                    select new {Name = cust.Name, City = cust.City};

 

  3.3 将内存中的靶子转换为 XML

图片 69图片 70

 1             //创建数据源
 2             var students = new List<Student>()
 3             {
 4                 new Student()
 5                 {
 6                     Age = 18,
 7                     Name = "小A",
 8                     Scores = new List<int>() {88,85,74,66 }
 9                 },
10                 new Student()
11                 {
12                     Age = 35,
13                     Name = "小B",
14                     Scores = new List<int>() {88,85,74,66 }
15                 },
16                 new Student()
17                 {
18                     Age = 28,
19                     Name = "小啥",
20                     Scores = new List<int>() {88,85,74,66 }
21                 }
22             };
23 
24             //创建查询
25             var studentsToXml = new XElement("Root",
26                 from student in students
27                 let x = $"{student.Scores[0]},{student.Scores[1]},{student.Scores[2]},{student.Scores[3]}"
28                 select new XElement("student",
29                 new XElement("Name", student.Name),
30                 new XElement("Age", student.Age),
31                 new XElement("Scores", x))
32             );
33 
34             //执行查询
35             Console.WriteLine(studentsToXml);

View Code

图片 71

 

  3.3 将内存中的对象转换为 XML

图片 72图片 73

 1             //创建数据源
 2             var students = new List<Student>()
 3             {
 4                 new Student()
 5                 {
 6                     Age = 18,
 7                     Name = "小A",
 8                     Scores = new List<int>() {88,85,74,66 }
 9                 },
10                 new Student()
11                 {
12                     Age = 35,
13                     Name = "小B",
14                     Scores = new List<int>() {88,85,74,66 }
15                 },
16                 new Student()
17                 {
18                     Age = 28,
19                     Name = "小啥",
20                     Scores = new List<int>() {88,85,74,66 }
21                 }
22             };
23 
24             //创建查询
25             var studentsToXml = new XElement("Root",
26                 from student in students
27                 let x = $"{student.Scores[0]},{student.Scores[1]},{student.Scores[2]},{student.Scores[3]}"
28                 select new XElement("student",
29                 new XElement("Name", student.Name),
30                 new XElement("Age", student.Age),
31                 new XElement("Scores", x))
32             );
33 
34             //执行查询
35             Console.WriteLine(studentsToXml);

View Code

图片 74

 

  3.4 对源元素执行操作

  输出序列可能无分包源序列的其他因素或因素属性。输出可能是经过将源元素用作输入参数计算起之价的队。

图片 75图片 76

 1             //数据源
 2             double[] radii = {1, 2, 3};
 3 
 4             //创建查询
 5             var query = from radius in radii
 6                 select $"{radius * radius * 3.14}";
 7 
 8             //执行查询
 9             foreach (var i in query)
10             {
11                 Console.WriteLine(i);
12             }

View Code

图片 77

   【备注】$”{radius
* radius * 3.14}” 相当于 string.Format(“{0}”,radius * radius *
3.14),这里以的凡 C# 6.0 的语法。

 

  3.4 对源元素执行操作

  输出序列可能未带有源序列的另因素或因素属性。输出可能是由此将源元素用作输入参数计算产生的价值的队。

图片 78图片 79

 1             //数据源
 2             double[] radii = {1, 2, 3};
 3 
 4             //创建查询
 5             var query = from radius in radii
 6                 select $"{radius * radius * 3.14}";
 7 
 8             //执行查询
 9             foreach (var i in query)
10             {
11                 Console.WriteLine(i);
12             }

View Code

图片 80

   【备注】$”{radius
* radius * 3.14}” 相当于 string.Format(“{0}”,radius * radius *
3.14),这里用的是 C# 6.0 的语法。

 

季、LINQ 查询操作的类型涉及

  LINQ
查询操作以数据源、查询本人以及查询执行中凡是强类型的。查询中变量的花色必须跟数据源中元素的色以及 foreach 语句子中迭代变量的类兼容。强类型可以保证在编译时捕获类型错误,以便就改正。

 

季、LINQ 查询操作的档次涉及

  LINQ
查询操作以数据源、查询本人和查询执行中凡强类型的。查询中变量的类型必须同数据源中元素的门类和 foreach 语句中迭代变量的品种兼容。强类型可以保证在编译时捕获类型错误,以便及时改正。

 

  4.1 不转换源数据的询问

  下图演示不对数据实施转换的 LINQ to Objects
查询操作。源包含一个字符串序列,查询输出为是一个字符串序列。 

图片 81

  ①数据源的类别参数决定限制变量的品类。

  ②拣的靶子的项目决定查询变量的项目。此处的 name 为一个字符串。因此,查询变量是一个 IEnumerable<字符串>。
 

  ③在 foreach 语句子被循环访问查询变量。因为查询变量是一个字符串序列,所以迭代变量也是一个字符串。
 

 

  4.1 不转换源数据的询问

  下图演示不对数据实施转换的 LINQ to Objects
查询操作。源包含一个字符串序列,查询输出为是一个字符串序列。 

图片 82

  ①数据源的项目参数决定限制变量的品种。

  ②精选的靶子的色决定查询变量的种。此处的 name 为一个字符串。因此,查询变量是一个 IEnumerable<字符串>。
 

  ③在 foreach 语词被循环访问查询变量。因为查询变量是一个字符串序列,所以迭代变量也是一个字符串。
 

 

  4.2 转换源数据的查询

  下图演示对数据实施简单转换的 LINQ to
SQL 查询操作。查询将一个 Customer 对象序列用作输入,并就选择结果丁的 Name 属性。因为 Name 是一个字符串,所以查询生成一个字符串序列作为出口。  

图片 83

  ①数据源的型参数决定限制变量的档次。

  ②select 语词返回 Name 属性,而非完全的 Customer 对象。因为 Name 是一个字符串,所以 custNameQuery 的类型参数是 string,而非Customer。
 

  ③以 custNameQuery 是一个字符串序列,所以 foreach 循环的迭代变量也须是 string

 

  下图演示另一样种转移。select 语句返回就捕获原始 Customer 对象的星星点点只分子的匿名类型。

图片 84

  ①数据源的档次参数始终为查询中的限制变量的类别。

  ②因为 select 语词生成匿名类型,所以必须使 var 隐式类型化查询变量。

  ③以查询变量的项目是隐式的,所以 foreach 循环中的迭代变量也不能不是隐式的。

 

  4.2 转换源数据的查询

  下图演示对数据实施简单转换的 LINQ to
SQL 查询操作。查询将一个 Customer 对象序列用作输入,并只挑结果负之 Name 属性。因为 Name 是一个字符串,所以查询生成一个字符串序列作为出口。  

图片 85

  ①数据源的门类参数决定限制变量的项目。

  ②select 语句返回 Name 属性,而不完全的 Customer 对象。因为 Name 是一个字符串,所以 custNameQuery 的种参数是 string,而非Customer。
 

  ③缘 custNameQuery 是一个字符串序列,所以 foreach 循环的迭代变量也亟须是 string

 

  下图演示另一样种易。select 语句子返回就捕获原始 Customer 对象的片独成员的匿名类型。

图片 86

  ①数据源的门类参数始终为查询中之克变量的项目。

  ②因为 select 语词生成匿名类型,所以要采取 var 隐式类型化查询变量。

  ③为查询变量的种是隐式的,所以 foreach 循环中之迭代变量也要是隐式的。

 

  4.3 让编译器推断类型信息

  您吗可以动用主要字 var,可用以查询操作中的旁部分变量。但是,编译器为查询操作中的各个变量提供强类型。  

图片 87

 

  4.3 让编译器推断类型信息

  您吗可以应用要字 var,可用以查询操作着之另外有变量。但是,编译器为查询操作中之一一变量提供强类型。  

图片 88

 

五、LINQ 中之询问语法和办法语法

  我们编辑的 LINQ 查询语法,在编译代码时,CLR
会将查询语法转换为艺术语法。这些措施调用标准查询运算符的名类似 WhereSelectGroupByJoinMax和 Average,我们吧是足以一直使用这些方法语法的。
 

  查询语法和法语法语义相同,但是,许多人手发现查询语法更简便、更易阅读。某些查询必须代表为方式调用。例如,必须以方式调用表示找元素的数量和指定的条件的询问。还须下方式需要找元素的尽深价值当来自序列的查询。System.Linq 命名空间中之规范查询运算符的参阅文档通常用办法语法。

 

五、LINQ 中的查询语法和方法语法

  我们编辑的 LINQ 查询语法,在编译代码时,CLR
会将查询语法转换为方式语法。这些办法调用标准查询运算符的称谓类似 WhereSelectGroupByJoinMax和 Average,我们吧是得直接以这些措施语法的。
 

  查询语法和章程语法语义相同,但是,许多人员发现查询语法更简明、更爱阅读。某些查询必须代表也法调用。例如,必须使用方法调用表示找元素的数及指定的尺度的询问。还非得运用方法要寻找元素的无限要命价值当起源序列的询问。System.Linq 命名空间受到之科班查询运算符的参照文档通常以方式语法。

 

  5.1 标准查询运算符扩展方法

图片 89图片 90

 1         static void Main(string[] args)
 2         {
 3             var nums = new int[4] { 1, 2, 3, 4 };
 4             
 5             //创建查询表达式
 6             var qureyNums = from n in nums
 7                             where n % 2 == 0
 8                             orderby n descending
 9                             select n;
10 
11             Console.WriteLine("qureyNums:");
12             foreach (var n in qureyNums)
13             {
14                 Console.WriteLine(n);
15             }
16     
17             //使用方法进行查询
18             var queryNums2 = nums.Where(n => n % 2 == 0).OrderByDescending(n => n);
19 
20             Console.WriteLine("qureyNums2:");
21             foreach (var n in queryNums2)
22             {
23                 Console.WriteLine(n);
24             }
25 
26             Console.Read();
27         }

下面的演示演示简单的询问表达式和编辑为根据方法的查询的语义上等同的询问。

图片 91

  两个示范的出口是相同的。您得看到零星栽形式之询问变量的品类是同样的:IEnumerable<T>。
 

  若要询问因方法的查询,让咱们越来越地解析其。注意,在表达式的右侧,where 子句现在代表也对 numbers 对象的实例方法,在公更调用该目标时该品种也 IEnumerable<int>。如果你熟悉泛型 IEnumerable<T> 接口,那么你尽管见面询问,它不具 Where 方法。但是,如果你当
Visual Studio IDE 中调用 IntelliSense
完成列表,那么你不仅拿见到 Where 方法,而且还见面看到许多外方法,如 SelectSelectManyJoin 和Orderby。下面是具标准查询运算符。 

图片 92

  尽管看起 IEnumerable<T> 似乎都受重新定义为囊括这些附加措施,但实际并非如此。这些标准查询运算符都是用作“扩展方法”实现之。

 

  5.1 标准查询运算符扩展方法

图片 93图片 94

 1         static void Main(string[] args)
 2         {
 3             var nums = new int[4] { 1, 2, 3, 4 };
 4             
 5             //创建查询表达式
 6             var qureyNums = from n in nums
 7                             where n % 2 == 0
 8                             orderby n descending
 9                             select n;
10 
11             Console.WriteLine("qureyNums:");
12             foreach (var n in qureyNums)
13             {
14                 Console.WriteLine(n);
15             }
16     
17             //使用方法进行查询
18             var queryNums2 = nums.Where(n => n % 2 == 0).OrderByDescending(n => n);
19 
20             Console.WriteLine("qureyNums2:");
21             foreach (var n in queryNums2)
22             {
23                 Console.WriteLine(n);
24             }
25 
26             Console.Read();
27         }

脚的演示演示简单的查询表达式和编制为依据方法的询问的语义上同一的查询。

图片 95

  两单示范的出口是平的。您可以见到个别种植形式之询问变量的路是如出一辙的:IEnumerable<T>。
 

  若一旦了解因方法的查询,让我们进一步地剖析其。注意,在表达式的右手,where 子句现在意味着也对 numbers 对象的实例方法,在您再次调用该目标时那列也 IEnumerable<int>。如果你熟悉泛型 IEnumerable<T> 接口,那么您就会询问,它不备 Where 方法。但是,如果你于
Visual Studio IDE 中调用 IntelliSense
完成列表,那么您不仅以视 Where 方法,而且还会见相不少别方,如 SelectSelectManyJoin 和Orderby。下面是持有专业查询运算符。 

图片 96

  尽管看起 IEnumerable<T> 似乎早已让再定义为囊括这些附加措施,但实则并非如此。这些规范查询运算符都是当“扩展方法”实现之。

 

  5.2 Lambda 表达式

  在前方的示范中,通知该法发挥式 (num % 2 == 0) 是作为内联参数。Where 方法:Where(num
=> num % 2 == 0) 此内联表达式称为 lambda
表达式。将代码编写为匿名方式要泛型委托或表达式树是同等种植便利的主意,否则编写起来便使累得几近。=> 是
lambda 运算符,可读吧“goes
to”。运算符左侧的 num 是输入变量,与查询表达式中的 num 相对应。编译器可想 num 的类别,因为她了解 numbers 是泛型 IEnumerable<T> 类型。lambda
表达式与查询语法中的表达式或任何其他 C#
表达式或报告句被之表达式相同;它可包方法调用和其它复杂逻辑。“返回值”就是表达式结果。
 

 

  5.2 Lambda 表达式

  以眼前的演示中,通知该条件达式 (num % 2 == 0) 是作为内联参数。Where 方法:Where(num
=> num % 2 == 0) 此内联表达式称为 lambda
表达式。将代码编写为匿名方式还是泛型委托或表达式树是一律栽便民的方式,否则编写起来就是假设麻烦得多。=> 是
lambda 运算符,可读也“goes
to”。运算符左侧的 num 是输入变量,与查询表达式中之 num 相对应。编译器可想 num 的型,因为它们了解 numbers 是泛型 IEnumerable<T> 类型。lambda
表达式与查询语法中之表达式或任何其他 C#
表达式或报句被的表达式相同;它可以概括方法调用和另复杂逻辑。“返回值”就是表达式结果。
 

 

  5.3 查询的组合性

  于面的代码示例中,请留心 OrderBy 方法是透过在对 Where 的调用中使用点运算符来调用的。Where 生成筛选序列,然后 Orderby 通过对拖欠队排序来对它们进行操作。因为查询会返回 IEnumerable,所以您可透过以计调整用链接以联名,在方语法中以这些查询组合起来。这就是是以您通过下查询语法编写查询时编译器在后台所实施之操作。并且鉴于查询变量不存储查询的结果,因此若可随时修改它还是以它因此作新查询的根底,即使在履其后。

 

  5.3 查询的组合性

  于面的代码示例中,请留心 OrderBy 方法是经在对 Where 的调用中运用点运算符来调用的。Where 生成筛选序列,然后 Orderby 通过对拖欠队排序来对它们进行操作。因为查询会返回 IEnumerable,所以您可经以计调整用链接以合,在方式语法中以这些查询组合起来。这就是是以您通过使用查询语法编写查询时编译器在后台所实施之操作。并且鉴于查询变量不存储查询的结果,因此若可随时修改它还是以它用作新查询的底子,即使在履其后。

 

传送门

  入门:《走进 LINQ
的世界》

  进阶:《LINQ
标准查询操作概述》(强烈推荐)

  技巧:《Linq To Objects –
如何操作字符串》 和
《Linq To Objects –
如何操作文件目录》

 

 


正文首联:http://www.cnblogs.com/liqingwen/p/5832322.html

【参考】https://msdn.microsoft.com/zh-cn/library/bb397897(v=vs.100).aspx

【来源】本文引用部分微软官方文档的图样

 

 

  

传送门

  入门:《走进 LINQ
的世界》

  进阶:《LINQ
标准查询操作概述》(强烈推荐)

  技巧:《Linq To Objects –
如何操作字符串》 和
《Linq To Objects –
如何操作文件目录》

 

 


正文首联:http://www.cnblogs.com/liqingwen/p/5832322.html

【参考】https://msdn.microsoft.com/zh-cn/library/bb397897(v=vs.100).aspx

【来源】本文引用部分微软官方文档的图样