查询是一种从数据源检索数据的表达式。查询通常用专门的查询语言来表示。随着时间的推移,人们已经为各种数据源开发了不同的语言;例如,用于关系数据库的 SQL 和用于 XML 的 XQuery。因此,开发人员不得不针对他们必须支持的每种数据源或数据格式而学习新的查询语言。LINQ 通过提供一种跨各种数据源和数据格式使用数据的一致模型,简化了这一情况。在 LINQ 查询中,始终会用到对象。可以使用相同的基本编码模式来查询和转换 XML 文档、SQL 数据库、ADO.NET 数据集、.NET 集合中的数据以及对其有 LINQ 提供程序可用的任何其他格式的数据。
查询操作的三个部分
所有 LINQ 查询操作都由以下三个不同的操作组成:
-
获取数据源。
-
创建查询。
-
执行查询。
下面的示例演示如何用源代码表示查询操作的三个部分。为了方便起见,此示例将一个整数数组用作数据源;但其中涉及的概念同样适用于其他数据源。本主题的其余部分也会引用此示例。
class IntroToLINQ
{
static void Main()
{
// The Three Parts of a LINQ Query:
// 1. Data source.
int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
// 2. Query creation.
// numQuery is an IEnumerable<int>
var numQuery =
from num in numbers
where (num % 2) == 0
select num;
// 3. Query execution.
foreach (int num in numQuery)
{
Console.Write("{0,1} ", num);
}
}
}
下图显示了完整的查询操作。在 LINQ 中,查询的执行与查询本身截然不同;换句话说,如果只是创建查询变量,则不会检索任何数据。
在上一个示例中,由于数据源是数组,因此它隐式支持泛型 IEnumerable<(Of <(T>)>) 接口。这一事实意味着该数据源可以用 LINQ 进行查询。在 foreach 语句中执行查询,而 foreach 要求使用 IEnumerable 或 IEnumerable<(Of <(T>)>)。支持 IEnumerable<(Of <(T>)>) 或派生接口(如泛型 IQueryable<(Of <(T>)>))的类型称为“可查询类型”。
可查询类型不需要进行修改或特殊处理就可以用作 LINQ 数据源。如果源数据还没有作为可查询类型出现在内存中,则 LINQ 提供程序必须以此方式表示源数据。例如,LINQ to XML 将 XML 文档加载到可查询的 XElement 类型中: