windows C#-LINQ查询

news/2024/11/15 12:54:34/

查询是一种从数据源检索数据的表达式。 不同的数据源具有不同的原生查询语言,例如,用于关系数据库的 SQL 和用于 XML 的 XQuery。 开发人员对于他们必须支持的每种数据源或数据格式,都必须学习一种新的查询语言。 LINQ 通过为各种数据源和数据格式提供一致的 C# 语言模型,简化了这一情况。 在 LINQ 查询中,你始终使用 C# 对象。 当有 LINQ 提供程序可用时,你可以使用相同的基本编码模式来查询和转换 XML 文档、SQL 数据库、.NET 集合中的数据以及任何其他格式的数据。

查询操作的三个部分

所有 LINQ 查询操作都由以下三个不同的操作组成:

  • 获取数据源;
  • 创建查询;
  • 执行查询;

下面的示例演示如何用源代码表示查询操作的三个部分。 为方便起见,此示例将一个整数数组用作数据源;但其中涉及的概念同样适用于其他数据源。 本文的其余部分也引用了此示例。

// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = [ 0, 1, 2, 3, 4, 5, 6 ];// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =from num in numberswhere (num % 2) == 0select num;// 3. Query execution.
foreach (int num in numQuery)
{Console.Write("{0,1} ", num);
}

下图演示完整的查询操作。 在 LINQ 中,查询的执行不同于查询本身。 换句话说,你不会通过创建查询变量来检索任何数据。

d93cc185f13249f6a72fd8017a878a2c.png

数据源

上例中的数据源是一个数组,它支持泛型 IEnumerable<T> 接口。 这一事实意味着该数据源可以用 LINQ 进行查询。 查询在 foreach 语句中执行,且 foreach 需要 IEnumerable 或 IEnumerable<T>。 支持 IEnumerable<T> 或派生接口(如泛型 IQueryable<T>)的类型称为可查询类型 。

可查询类型不需要进行修改或特殊处理就可以用作 LINQ 数据源。 如果源数据还没有作为可查询类型出现在内存中,则 LINQ 提供程序必须以此方式表示源数据。 例如,LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中:

// Create a data source from an XML document.
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");

使用 EntityFramework,你在 C# 类与数据库架构之间创建对象关系映射。 你针对这些对象编写查询,然后 EntityFramework 在运行时处理与数据库的通信。 下例中,Customers 表示数据库中的特定表,而查询结果的类型 IQueryable<T> 派生自 IEnumerable<T>。

Northwnd db = new Northwnd(@"c:\northwnd.mdf");// Query for customers in London.
IQueryable<Customer> custQuery =from cust in db.Customerswhere cust.City == "London"select cust;

基本规则很简单:LINQ 数据源是支持泛型 IEnumerable<T> 接口(或者是继承该接口的接口,通常表示为 IQueryable<T>)的任何对象。

支持非泛型 IEnumerable 接口的类型(如 ArrayList)还可用作 LINQ 数据源。 

查询

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

上一个示例中的查询从整数数组中返回所有偶数。 该查询表达式包含三个子句:from、where 和 select。 (如果你熟悉 SQL,你会注意到这些子句的顺序与 SQL 中的顺序相反。)from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素的类型。 本部分详细介绍了所有查询子句。 目前需要注意的是,在 LINQ 中,查询变量本身不执行任何操作并且不返回任何数据。 它只是存储在以后某个时刻执行查询时为生成结果而必需的信息。 

还可以使用方法语法来表示查询。

标准查询运算符按执行方式的分类

标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行。 使用延迟执行的查询运算符可以进一步分为两种类别:流式处理和非流式处理。

即时

立即执行指的是读取数据源并执行一次运算。 返回标量结果的所有标准查询运算符都立即执行。 Count、Max、Average 和 First 就属于此类查询。 由于查询本身必须使用 foreach 来返回结果,因此这些方法在执行时不使用显式 foreach 语句。 这些查询返回单个值,而不是 IEnumerable 集合。 可以使用 Enumerable.ToList 或 Enumerable.ToArray 方法强制任何查询立即执行。 立即执行可重用查询结果,而不是查询声明。 结果被检索一次,然后存储以供将来使用。 下面的查询返回源数组中偶数的计数:

var evenNumQuery =from num in numberswhere (num % 2) == 0select num;int evenNumCount = evenNumQuery.Count();

要强制立即执行任何查询并缓存其结果,可调用 ToList 或 ToArray 方法。

List<int> numQuery2 =(from num in numberswhere (num % 2) == 0select num).ToList();// or like this:
// numQuery3 is still an int[]var numQuery3 =(from num in numberswhere (num % 2) == 0select num).ToArray();

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

已推迟

延迟执行指的是不在代码中声明查询的位置执行运算。 仅当对查询变量进行枚举时才执行运算,例如通过使用 foreach 语句执行。 查询的执行结果取决于执行查询而非定义查询时的数据源内容。 如果多次枚举查询变量,则每次结果可能都不同。 几乎所有返回类型为 IEnumerable<T> 或 IOrderedEnumerable<TElement> 的标准查询运算符皆以延迟方式执行。 延迟执行提供了查询重用功能,因为在每次循环访问查询结果时,查询都会从数据源中提取更新的数据。 以下代码演示了延迟执行的示例:

foreach (int num in numQuery)
{Console.Write("{0,1} ", num);
}

 

foreach 语句也是检索查询结果的地方。 例如,在上一个查询中,迭代变量 num 保存了返回的序列中的每个值(一次保存一个值)。

由于查询变量本身从不保存查询结果,因此你可以重复执行它来检索更新的数据。 例如,单独的应用程序可能会不断更新数据库。 在应用程序中,你可以创建一个检索最新数据的查询,并可以不时地执行该查询以便检索更新的结果。

使用延迟执行的查询运算符可以进一步分类为流式处理和非流式处理。

流式处理

流式处理运算符不需要在生成元素前读取所有源数据。 在执行时,流式处理运算符一边读取每个源元素,一边对该源元素执行运算,并在可行时生成元素。 流式处理运算符将持续读取源元素直到可以生成结果元素。 这意味着可能要读取多个源元素才能生成一个结果元素。

非流式处理

非流式处理运算符必须先读取所有源数据,然后才能生成结果元素。 排序或分组等运算均属于此类别。 在执行时,非流式处理查询运算符读取所有源数据,将其放入数据结构,执行运算,然后生成结果元素。

LINQ to objects

“LINQ to Objects”是指将 LINQ 查询直接用于任何 IEnumerable 或 IEnumerable<T> 集合。 可以使用 LINQ 来查询任何可枚举的集合,例如 List<T>、Array 或 Dictionary<TKey,TValue>。 该集合可以是用户定义的集合,也可以是由 .NET API 返回的类型。 而采用 LINQ 方法,只需编写描述要检索的内容的声明性代码。 LINQ to Objects 很好地介绍了如何使用 LINQ 进行编程。

LINQ 查询与传统 foreach 循环相比具有三大优势:

  • 它们更简明、更易读,尤其在筛选多个条件时。
  • 它们使用最少的应用程序代码提供强大的筛选、排序和分组功能。
  • 无需修改或只需做很小的修改即可将它们移植到其他数据源。

要对数据执行的操作越复杂,就越能体会到 LINQ 相较于传统迭代技术的优势。

在内存中存储查询结果

查询基本上是针对如何检索和组织数据的一套说明。 当请求结果中的每个后续项目时,查询将延迟执行。 使用 foreach 循环访问结果时,项将在受到访问时返回。 若要在不执行 foreach 循环的情况下评估查询并存储其结果,只需调用查询变量上的以下方法之一:

  • ToList
  • ToArray
  • ToDictionary
  • ToLookup

在存储查询结果时,应将返回的集合对象分配给一个新变量,如下面的示例所示:

List<int> numbers = [1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20];IEnumerable<int> queryFactorsOfFour =from num in numberswhere num % 4 == 0select num;// Store the results in a new variable
// without executing a foreach loop.
var factorsofFourList = queryFactorsOfFour.ToList();// Read and write from the newly created list to demonstrate that it holds data.
Console.WriteLine(factorsofFourList[2]);
factorsofFourList[2] = 0;
Console.WriteLine(factorsofFourList[2]);

 


http://www.ppmy.cn/news/1547204.html

相关文章

Linux的进程,线程;FreeRTOS的任务

Linux 进程与线程 进程 (Process) 定义:进程是操作系统进行资源分配和调度的基本单位。每个进程都有独立的地址空间,包括代码段、数据段、堆栈等。资源:每个进程拥有独立的内存空间、文件描述符、环境变量等。创建:通常通过 fork 系统调用创建新进程,子进程继承父进程的大…

Word VBA如何间隔选中多个(非连续)段落

实例需求&#xff1a;Word文档中的有多个段落&#xff0c;段落总数量不确定&#xff0c;现在需要先选中所有基数段落&#xff0c;即&#xff1a;段落1&#xff0c;段落3 … &#xff0c;然后一次性设置粗体格式。 也许有的读者会认为这个无厘头的需求&#xff0c;循环遍历遍历文…

linux startup.sh shutdown.sh (kkFileView)

linux启动脚本和关闭脚本startup.sh shutdown.sh &#xff08;kkFileView&#xff09; startup.sh DIR_HOME("/opt/openoffice.org3" "/opt/libreoffice" "/opt/libreoffice6.1" "/opt/libreoffice7.0" "/opt/libreoffice7.1&q…

Zabbix使用

1.Zabbix术语 术语名称术语解释主机&#xff08;Host&#xff09;一台你想监控的网络设备&#xff0c;用 IP 或域名表示监控项&#xff08;Item&#xff09;接收的主机的特定数据&#xff0c;一个度量数据触发器(Trigger)一个被用于定义问题阈值和“评估”监控项接收到的数据的…

HBase理论_HBase架构组件介绍

近来有些空闲时间&#xff0c;正好最近也在开发HBase相关内容&#xff0c;借此整理一下学习和对HBase组件的架构的记录和个人感受&#xff0c;付出了老夫不少心血啊&#xff0c;主要介绍的就是HBase的架构设计以及我的拓展内容。内容如有不当或有其他理解 matirx70163.com HB…

计算机网络学习

1.2 因特网概述_哔哩哔哩_bilibili 在以上视频进行学习 1. 网络、互联网和因特网 网络是由若干节点和连接这些节点的链路组成 多个网络可以通过路由器互联起来&#xff0c;构成一个覆盖范围更大的网络&#xff0c;即互联网。因此互联网是“网络中的网络” 因特网是世界上最…

CSS样式实现3D效果

CSS 3D效果是通过CSS3中的transform和perspective等属性来实现的。这些属性允许你创建具有深度感和三维外观的网页元素。以下是一些常见的CSS 3D效果及其实现方法&#xff1a; 1. 3D旋转&#xff08;Rotate&#xff09; 使用transform: rotateX(), rotateY(), rotateZ()来分别…

1. kafka分布式环境搭建

一. 集群规划 主机名IP组件hadoop1192.168.205.154zookeeper, kafkahadoop2192.168.205.155kafkahadoop3192.168.205.156kafka kafka版本&#xff1a;3.6.0二. 集群部署 安装JDK&#xff0c;具体安装过程此处不赘述。 安装zookeeper&#xff0c;本次采用单机模式部署在hadoo…