系列目录    【已更新最新开发文章,点击查看详细】 <https://www.cnblogs.com/SavionZhang/p/11229640.html>
查询 是一种从数据源检索数据的表达式。 查询通常用专门的查询语言来表示。 随着时间的推移,人们已经为各种数据源开发了不同的语言;例如,用于关系数据库的
SQL 和用于 XML 的 XQuery。 因此,开发人员对于他们必须支持的每种数据源或数据格式,都不得不学习一种新的查询语言。 LINQ 
通过提供一种跨各种数据源和数据格式使用数据的一致模型,简化了这一情况。 在 LINQ 查询中,始终会用到对象。 可以使用相同的基本编码模式来查询和转换 XML
文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的数据以及 LINQ 提供程序可用的任何其他格式的数据。
查询操作的三个部分
所有 LINQ 查询操作都由以下三个不同的操作组成:

*
获取数据源。

*
创建查询。

*
执行查询。

下面的示例演示如何用源代码表示查询操作的三个部分。 为方便起见,此示例将一个整数数组用作数据源;但其中涉及的概念同样适用于其他数据源。 
本主题的其余部分也会引用此示例。
class IntroToLINQ { static void Main() { // 1. 数据源 int[] numbers = new int[7] {
0, 1, 2, 3, 4, 5, 6 }; // 2. 查询表达式 numQuery 是 IEnumerable<int> 类型 var numQuery =
from num in numbers where (num % 2) == 0 select num; // 3. 执行查询 foreach (int num
in numQuery) { Console.Write("{0,1} ", num); } } }
下图演示完整的查询操作。 在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。


数据源
上例中,数据源是一个数组,因此它隐式支持泛型 IEnumerable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.ienumerable-1>
 接口。 这一事实意味着该数据源可以用 LINQ 进行查询。 查询在 foreach 语句中执行,且 foreach 需要 IEnumerable
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.ienumerable> 或 
IEnumerable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.ienumerable-1>
。 支持 IEnumerable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.ienumerable-1>
 或派生接口(如泛型 IQueryable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.iqueryable-1>
)的类型称为可查询类型。

可查询类型不需要进行修改或特殊处理就可以用作 LINQ 数据源。 如果源数据还没有作为可查询类型出现在内存中,则 LINQ 提供程序必须以此方式表示源数据。 
例如,LINQ to XML 将 XML 文档加载到可查询的 XElement
<https://docs.microsoft.com/zh-cn/dotnet/api/system.xml.linq.xelement> 类型中:
// using System.Xml.Linq; XElement contacts = XElement.Load(@"
c:\myContactList.xml");// 从 xml 文件创建数据源
借助 LINQ to SQL,首先在 Visual Studio 中手动或使用 Visual Studio 中的 LINQ to SQL 工具
<https://docs.microsoft.com/zh-cn/visualstudio/data-tools/linq-to-sql-tools-in-visual-studio2>
在设计时创建对象关系映射。 针对这些对象编写查询,然后由 LINQ to SQL 在运行时处理与数据库的通信。 下例中,Customers
 表示数据库中的特定表,而查询结果的类型 IQueryable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.iqueryable-1> 派生自 
IEnumerable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.ienumerable-1>

Northwnd db = new Northwnd(@"c:\northwnd.mdf"); // 查询城市名称为 London 的客户
IQueryable<Customer> custQuery =from cust in db.Customers where cust.City == "
London" select cust;
有关如何创建特定类型的数据源的详细信息,请参阅各种 LINQ 提供程序的文档。 但基本规则很简单:LINQ 数据源是支持泛型 IEnumerable<T>
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.generic.ienumerable-1>
 接口或从中继承的接口的任意对象。

支持非泛型 IEnumerable
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.ienumerable?view=netframework-4.8>
接口的类型(如ArrayList
<https://docs.microsoft.com/zh-cn/dotnet/api/system.collections.arraylist?view=netframework-4.8>
)还可用作 LINQ 数据源。 有关详细信息,请参阅如何:使用 LINQ 查询 ArrayList (C#)
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/how-to-query-an-arraylist-with-linq>

查询
查询指定要从数据源中检索的信息。 查询还可以指定在返回这些信息之前如何对其进行排序、分组和结构化。 查询存储在查询变量中,并用查询表达式进行初始化。 
为使编写查询的工作变得更加容易,C# 引入了新的查询语法。

上一个示例中的查询从整数数组中返回所有偶数。 该查询表达式包含三个子句:from、where 和 select。 (如果熟悉
SQL,会注意到这些子句的顺序与 SQL 中的顺序相反。)from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素的类型。
LINQ 查询表达式
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/linq-query-expressions/index>
一节中详细讨论了这些子句和其他查询子句。 目前需要注意的是,在 LINQ 中,查询变量本身不执行任何操作并且不返回任何数据。 
它只是存储在以后某个时刻执行查询时为生成结果而必需的信息。 有关在后台如何构造查询的详细信息,请参阅标准查询运算符概述 (C#)
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/standard-query-operators-overview>


还可以使用方法语法来表示查询。 有关详细信息,请参阅 LINQ 中的查询语法和方法语法
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/query-syntax-and-method-syntax-in-linq>

查询执行
延迟执行

如前所述,查询变量本身只存储查询命令。 查询的实际执行将推迟到在 foreach 语句中循环访问查询变量之后进行。 此概念称为延迟执行
,下面的示例对此进行了演示:
// 执行查询 foreach (int num in numQuery) { Console.Write("{0,1} ", num); }
foreach 语句也是检索查询结果的地方。 例如,在上一个查询中,迭代变量 num 保存了返回的序列中的每个值(一次保存一个值)。

由于查询变量本身从不保存查询结果,因此可以根据需要随意执行查询。 例如,可以通过一个单独的应用程序持续更新数据库。 
在应用程序中,可以创建一个检索最新数据的查询,并可以按某一时间间隔反复执行该查询以便每次检索不同的结果。

强制立即执行

对一系列源元素执行聚合函数的查询必须首先循环访问这些元素。 Count、Max、Average 和 First 就属于此类查询。 由于查询本身必须使用 
foreach 以便返回结果,因此这些查询在执行时不使用显式 foreach 语句。 另外还要注意,这些类型的查询返回单个值,而不是 IEnumerable
 集合。 下面的查询返回源数组中偶数的计数:
var evenNumQuery = from num in numbers where (num % 2) == 0 select num; int
evenNumCount = evenNumQuery.Count();
要强制立即执行任何查询并缓存其结果,可调用 ToList
<https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.tolist> 或 
ToArray
<https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.enumerable.toarray> 方法。
List<int> numQuery2 = (from num in numbers where (num % 2) == 0 select num).
ToList(); var numQuery3 = (from num in numbers where (num % 2) == 0 select num).
ToArray();
此外,还可以通过在紧跟查询表达式之后的位置放置一个 foreach 循环来强制执行查询。 但是,通过调用 ToList 或 ToArray
,也可以将所有数据缓存在单个集合对象中。

其他技术请参考

* C# 中的 LINQ 入门
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/getting-started-with-linq>
* 演练:用 C# 编写查询
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/linq/walkthrough-writing-queries-linq>
* LINQ 查询表达式
<https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/linq-query-expressions/index>
* foreach, in
<https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/foreach-in>
* 查询关键字 (LINQ)
<https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/query-keywords>
 
系列目录    【已更新最新开发文章,点击查看详细】
<https://www.cnblogs.com/SavionZhang/p/11229640.html>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信