C#3.0新增功能09 LINQ 基础02 LINQ 查询简介
查询 是一种从数据源检索数据的表达式。 查询通常用专门的查询语言来表示。 随着时间的推移,人们已经为各种数据源开发了不同的语言;例如,用于关系数据库的 SQL 和用于 XML 的 XQuery。 因此,开发人员对于他们必须支持的每种数据源或数据格式,都不得不学习一种新的查询语言。 LINQ 通过提供一种跨各种数据源和数据格式使用数据的一致模型,简化了这一情况。 在 LINQ 查询中,始终会用到对象。 可以使用相同的基本编码模式来查询和转换 XML 文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的数据以及 LINQ 提供程序可用的任何其他格式的数据。
所有 LINQ 查询操作都由以下三个不同的操作组成:
获取数据源。
创建查询。
执行查询。
下面的示例演示如何用源代码表示查询操作的三个部分。 为方便起见,此示例将一个整数数组用作数据源;但其中涉及的概念同样适用于其他数据源。 本主题的其余部分也会引用此示例。
class IntroToLINQ
{
static void Main()
{ // 1. 数据源
int[] numbers = new int[] { , , , , , , }; // 2. 查询表达式 numQuery 是 IEnumerable<int> 类型
var numQuery =
from num in numbers
where (num % ) ==
select num; // 3. 执行查询
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
下图演示完整的查询操作。 在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。

上例中,数据源是一个数组,因此它隐式支持泛型 IEnumerable<T> 接口。 这一事实意味着该数据源可以用 LINQ 进行查询。 查询在 foreach 语句中执行,且 foreach 需要 IEnumerable 或 IEnumerable<T>。 支持 IEnumerable<T> 或派生接口(如泛型 IQueryable<T>)的类型称为可查询类型。
可查询类型不需要进行修改或特殊处理就可以用作 LINQ 数据源。 如果源数据还没有作为可查询类型出现在内存中,则 LINQ 提供程序必须以此方式表示源数据。 例如,LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中:
// using System.Xml.Linq;
XElement contacts = XElement.Load(@"c:\myContactList.xml");// 从 xml 文件创建数据源
借助 LINQ to SQL,首先在 Visual Studio 中手动或使用 Visual Studio 中的 LINQ to SQL 工具在设计时创建对象关系映射。 针对这些对象编写查询,然后由 LINQ to SQL 在运行时处理与数据库的通信。 下例中,Customers 表示数据库中的特定表,而查询结果的类型 IQueryable<T> 派生自 IEnumerable<T>。
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> 接口或从中继承的接口的任意对象。
支持非泛型 IEnumerable接口的类型(如 ArrayList)还可用作 LINQ 数据源。 有关详细信息,请参阅如何:使用 LINQ 查询 ArrayList (C#)。
查询指定要从数据源中检索的信息。 查询还可以指定在返回这些信息之前如何对其进行排序、分组和结构化。 查询存储在查询变量中,并用查询表达式进行初始化。 为使编写查询的工作变得更加容易,C# 引入了新的查询语法。
上一个示例中的查询从整数数组中返回所有偶数。 该查询表达式包含三个子句:from、where 和 select。 (如果熟悉 SQL,会注意到这些子句的顺序与 SQL 中的顺序相反。)from 子句指定数据源,where 子句应用筛选器,select 子句指定返回的元素的类型。LINQ 查询表达式一节中详细讨论了这些子句和其他查询子句。 目前需要注意的是,在 LINQ 中,查询变量本身不执行任何操作并且不返回任何数据。 它只是存储在以后某个时刻执行查询时为生成结果而必需的信息。 有关在后台如何构造查询的详细信息,请参阅标准查询运算符概述 (C#)。
还可以使用方法语法来表示查询。 有关详细信息,请参阅 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 % ) ==
select num; int evenNumCount = evenNumQuery.Count();
要强制立即执行任何查询并缓存其结果,可调用 ToList 或 ToArray 方法。
List<int> numQuery2 =
(from num in numbers
where (num % ) ==
select num).ToList(); var numQuery3 =
(from num in numbers
where (num % ) ==
select num).ToArray();
此外,还可以通过在紧跟查询表达式之后的位置放置一个 foreach 循环来强制执行查询。 但是,通过调用 ToList 或 ToArray,也可以将所有数据缓存在单个集合对象中。
其他技术请参考
C#3.0新增功能09 LINQ 基础02 LINQ 查询简介的更多相关文章
- C#3.0新增功能09 LINQ 基础01 语言集成查询
连载目录 [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称. 数据查询历来都表示为简单的字符串,没有编译时类型检查或 Inte ...
- C#3.0新增功能09 LINQ 基础05 使用 LINQ 进行数据转换
连载目录 [已更新最新开发文章,点击查看详细] 语言集成查询 (LINQ) 不只是检索数据. 它也是用于转换数据的强大工具. 通过使用 LINQ查询,可以使用源序列作为输入,并通过多种方式对其进 ...
- C#3.0新增功能09 LINQ 标准查询运算符 01 概述
连载目录 [已更新最新开发文章,点击查看详细] 标准查询运算符 是组成 LINQ 模式的方法. 这些方法中的大多数都作用于序列:其中序列指其类型实现 IEnumerable<T> 接 ...
- C#3.0新增功能09 LINQ 标准查询运算符 03 按执行方式的分类
连载目录 [已更新最新开发文章,点击查看详细] 标准查询运算符方法的 LINQ to Objects 实现主要通过两种方法之一执行:立即执行和延迟执行.使用延迟执行的查询运算符可以进一步分为两种 ...
- C#3.0新增功能09 LINQ 基础04 基本 LINQ 查询操作
连载目录 [已更新最新开发文章,点击查看详细] 本篇介绍 LINQ 查询表达式和一些在查询中执行的典型操作. 获取数据源 在 LINQ 查询中,第一步是指定数据源. 和大多数编程语言相同,在使用 ...
- C#3.0新增功能09 LINQ 基础07 LINQ 中的查询语法和方法语法
连载目录 [已更新最新开发文章,点击查看详细] 介绍性的语言集成查询 (LINQ) 文档中的大多数查询是使用 LINQ 声明性查询语法编写的.但是在编译代码时,查询语法必须转换为针对 .NET ...
- C#3.0新增功能09 LINQ 基础03 LINQ 和泛型类型
连载目录 [已更新最新开发文章,点击查看详细] LINQ 查询基于 .NET Framework 版本 2.0 中引入的泛型类型. 无需深入了解泛型即可开始编写查询. 但是,可能需要了解 2 个 ...
- C#3.0新增功能09 LINQ 基础08 支持 LINQ 的 C# 功能
连载目录 [已更新最新开发文章,点击查看详细] 查询表达式 查询表达式使用类似于 SQL 或 XQuery 的声明性语法来查询 IEnumerable 集合. 在编译时,查询语法转换为对 LIN ...
- C#3.0新增功能09 LINQ 基础06 LINQ 查询操作中的类型关系
连载目录 [已更新最新开发文章,点击查看详细] 若要有效编写查询,应了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. ...
随机推荐
- Linux之mysql安装
查看文件内容的命令有很多:cat, tac, more, less, head, tail, nl. cat由第一行开始显示档案内容:tac从最后一行开始显示,可以看出tac是cat的倒着写:more ...
- Qt for android触摸手势事件QGestureEvent
在触摸设备上可以使用Qt的手势事件 要激活手势事件,需要执行以下操作: 第一步,为QWidget控件注册手势事件 QList<Qt::GestureType> gestures; gest ...
- 《C++ Primer》读书笔记 第三章
1.注意:头文件不应包含using声明.因为头文件的内容会拷贝到所有引用他的文件中去,对于某些程序来说,由于不经意间包含了一些名字,可能会产生名字冲突.2.string类型的读入:用cin读入stri ...
- 生成sql server 数据库 脚本的 存储过程和调用
USE [db_datadown] GO /****** Object: StoredProcedure [dbo].[GetTBScript] Script Date: 03/05/2015 09: ...
- HTML连载13-CSS基本格式以及文字相关的属性
一.CSS格式 1.注意点: (1)style标签必须写在head标签的开始标签和结束标签之间(也就是必须和title标签师兄弟关系) (2)style标签中的属性type属性其实可以不写,默认就是t ...
- nice-validator表单验证插件的简单使用
前言 前端表单校验是过滤无效数据.假数据.有毒数据的第一步,是数据安全的第一道关卡,虽然我们不能100%相信客户端提交的数据(真正的校验还得在服务端进行),但设置前端表单校验也是至关重要的,自己写逻辑 ...
- KNN算法——分类部分
1.核心思想 如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.也就是说找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该 ...
- HBase 学习之路(九)——HBase容灾与备份
一.前言 本文主要介绍Hbase常用的三种简单的容灾备份方案,即CopyTable.Export/Import.Snapshot.分别介绍如下: 二.CopyTable 2.1 简介 CopyTabl ...
- 【静态NAT】 为什么子网可以ping父网,但是父网ping不通子网?
为什么子网可以ping父网,但是父网ping不通子网? 这就好比在公网中ping一个192.168.0.x的子网,roter无法找到这个子网的地址,所以会把package丢掉. 如何解决呢,可以在路由 ...
- Paxos算法——前世
Paxos算法是基于消息传递且具有高度容错特性的一致性算法.我们将从一个简单的问题开始,逐步的改进我们的设计方案,最终得到Paxos,一个可以在逆境下工作的协议. 一.客户端-服务器模型 我们从最小的 ...