LINQ in Action 一书第一章翻译原稿
前言
第一章 开始入门
本章引入 LINQ 技术和了 C# 和 VB 语言增强功能。章一列出 LINQ、 其历史、 使用对象、 XML
和 SQL ,和快速 “ Hello World ” 示例。 第 2 章引入了所有提供最新版本的 C# 和 VB.NET,
要启用 LINQ 的新的语言功能。 第 3 章涵盖 LINQ 的技术基础,并显示它们如何结合在一起。
第一节 简介
本节包括
LINQ 的起源
LINQ 的设计模式
第一步 LINQ to Objects, LINQ to XML,和 LINQ to SQL
软件初看起来是很简单的。它无非处理两件事情:代码和数据。但他也并不简单,它涉及的主要活动之一是编写处理数据的代码。若要编写代码,我们可以从各种编程语言选择。选择语言会涉及到团队掌握技术情况、公司的政策及业务的连贯性等等。
任何语言最终指向你要处理的数据。数据可能是磁盘上的一个文件、数据库里的一张表或者是一个从网络下载的XML文档、或者,通常您必须处理的所有这些组合。最终你将要处理的数据将是您做的每个
项目。
处理数据是开发人员最常见的任务之一,我们期望像.NET Framework 提供一个简单的方法来处理数据就像JAVA 的 Hibernate一样方便。.NET 并提供对处理数据的广泛支持。但是,您将看到某些方面尚未达到:即更深的语言和数据集成。这就是 LINQ 到对象、 LINQ 到 XML 和 LINQ 到 SQL 运用。
我们这本书中所讨论的就是设计作为一种编写代码的新技术方式。我们首先会为您阐述为什要添加LINQ这种工具。 我们亦会引入 LINQ 如何扩展编程语言。
1.1.1 概述
LINQ是数据和编程语言之间的桥梁也是一种链接他们的必要节。LINQ 统一数据访问,无论何种数据源,并允许混合使用来自不同类型的数据源。它允许查询和设置相关操作,为数据库提供类似于 SQL 语句。虽然LINQ集成直接在通过一组对这些语言的扩展的.NET 语言如 C# 和 Visual Basic 中的查询: LINQ 含义指语言集成查询。在LINQ之前,我们不得不使用通用语言如 C# 或 VB.NET 编写每个应用程序中调试类似 SQL、 XML 或 XPath 一起各种技术的不同语言和 ADO.NET 或System.Xml 等的 API。当然这种方法有几个缺点,LINQ 全面涉及这几个领域。 它有助于我们避免我们通常会产生问题如:使用关系数据的对象的 XML,而且使用LINQ 将简化 一些处理XML关系数据的任务。
LINQ 主要方面之一是它被设计能用于任何类型的对象或数据源,并为这些对象或数据源提供一致的编程模型。其语法和概念在使用中都是相同的:您可以学习如何使用 LINQ 对数组或集合进行处理,你也知道大部分利用 LINQ 操作一个数据库或 XML 文件所需的方法。LINQ 的另一个重要方面是使用它时会让您工作在一个强类型化的环境。其它好处还包括编译时检查您的查询,以及从 Visual Studio 的IntelliSense 功能里的包含友好的提示。LINQ 将显著改善如何处理和操作与您的应用程序和组件的数据的一些方面。您将了解到怎样使用LINQ来建立程序的模型。也许你会感觉很短时间内编写更多的代码。
您可以根据设计模式使用LINQ对程序语言进行扩展。
您首先将看到如何使用 LINQ 用于处理对象、 XML 文档、 关系数据库或其他类型的数据的工具集。 然后,您将看到如何 使用LINQ 在类似 C# 和 VB.NET 的编程语言上的扩展。
1.1.2 作为工具集的LINQ
LINQ 提供了很多可能性。它显著会更改如何处理和操作与您的应用程序和组件的数据的一些方面。在这本书我们将详细使用三个主要风格的 LINQ 或 LINQ 提供程序 — LINQ 到对象、 LINQ to SQL 和 LINQ to XML,分别 — 2、 3 及 4 章的一部分。这些三种 LINQ 提供程序方法形成一系列工具,可分别用于特定需要或合并功能强大的解决方案。
在这本书我们将重点放在 LINQ 到对象、 LINQ to SQL 和 LINQ to XML ,但 LINQ 是开放新数据源。这三个主要 LINQ 提供方法就是这本书中讨论是基于构建的一个常见的 LINQ 基础。这个基础包含一组构建基块包括查询运算符、 查询表达式和允许 LINQ 工具集要扩展的表达式集。
可以创建其他的 LINQ 的变种,来提供对不同类型的数据源的访问。可以使用由软件提供商打包的 LINQ 并且您可以也创建自己的实现,正如您 第ll 和 12 章中看到的,包括 LINQ的扩展。可以使用LINQ 操作包括文件系统、 Active Directory、 WMI、 Windows 事件日志或任何其他数据源或 API。您会在此当中收益,因为他会帮助你处理大量数据。事实上,微软已经提供了比只 LINQ to Objects、 LINQ to SQL 和 LINQ to XML 的更多 LINQ 提供程序。其中两种是 LINQ to DataSet 和 LINQ 到 Entities (以使用新的 ADO.NET Entity Framework)。我们将在这本书第二个和第三个部分中介绍这些工具。现在让我们看图1.1构建块、 LINQ 提供程序和可以使用 LINQ 查询的数据源。图 1.1 说明如何我们可以代表 LINQ 构建基块和在关系图中的工具集。
LINQ 提供程序载图 1.1 不是独立工具。他们可直接用于您的编程语言中,因为 LINQ 框架是一套语言扩展。下一节中进行要进行详细介绍。
1.1.3 作为语言扩展的 LINQ
您可以通过LINQ来编写针对各种数据源的查询访问信息。您不必在使用SQL语法,因为LINQ提供了c#语言来处理,并提供了相同的类型及表达的功能。这是很重要的因为像一个 LINQ 提供了一个声明性方法允许您编写更面向对象的程序。
列表 1.1 显示示例 可以使用 LINQ编写C# 代码。
列出使用 LINQ 查询数据库,并创建 XML 文档的 1.1 示例代码
var contacts = ---------------从数据库检索客户表
from customer in db.Customers
where customer.Name.StartsWith("A") && customer.Orders.Count > 0
orderby customer.Name
select new { customer.Name, customer.Phone };
var xml = ---------------从客户列表生成 XML 数据
new XElement("contacts",
from contact in contacts
select new XElement("contact",
new XAttribute("name", contact.Name),
new XAttribute("phone", contact.Phone)
)
);
这段代码含义是从数据库中提取数据并从中创建一个 XML 文档写入所需内容。使用LINQ您会感觉到更容易、更自然。您将很快看到更多 LINQ 查询,但目前集中在语言方面。与from, where, orderby,和select 关键字在表里,很明显他们已经扩展进c#的LINQ工具里。
我们刚才所展示的是 C# 代码,但 LINQ 跨编程语言提供常见查询体系结构。他工作在 C# 3.0 and VB.NET 9.0 (即 VB 2008),因此需要专用的编译器,但是,可以其移植到其他.NET 语言。从目前来看F#已经有了LINQ功能,未来会有更多.NET语言得到LINQ的支持。
图 1.2 显示用于探讨对象、 XML 或数据表的典型语言集成查询。
图中的查询使用的是在 C#语法而不是在新的语言。LINQ并不是一种新的语言。它被集成到 C# 和 VB.NET。 此外,LINQ 可以用于避免.NET 编程语言与 SQL、 XSL 或其他特定于数据的语言想混淆。 LINQ 使查询通过多种类型的数据存储到编程语言的语言特定扩展集中。您可以把linq视为通用远程控制。有时,您 会使用它来查询数据库 ;在其他方面,您也可以查询 XML 文档。您只需使用您喜欢的编程语言不必切换到SQL 或 XQuery 等查询语言。
在第 2 章我们将为您展示如何编写已扩展到支持 LINQ 的详情。
1.2 为什么我们需要LINQ
我们只给您提供简略讲了LINQ。此时最大的问题是:为什么我们希望使用 LINQ 之类的工具?为什么不使用以前其它的工具呢?LINQ创建在程序语法里,也同存在于关系数据库和XML文档里。
LINQ 来源于项目是一个简单的事实:在应用程序中用来驱动和与数据库进行连接。因此应用程序中只懂一门c#语言是不能满族需求的,你还要学习另一些语言,例如SQL语法,配合连同 C# 以形成完整应用程序的 API。
我们将首先来看一段使用标准的.NET API 的数据访问代码。我们会指出,在这种代码中遇到的常见问题。然后,我们将通过显示如何这些存在问题与其他类型的数据如 XML。你将看到LINQ 地址之间数据源的一般不匹配和编程语言扩展我们的分析。最后,很少精短的代码示例将向您展示 LINQ 是如何解决问题的。
1.2.1常见问题
应用程序中经常使用数据库,要求.NET Framework 处理需要可以访问存储在该数据的 API。当然这是应用程序首要的任务之一。 .NET Framework 类库 (FCL) 包括 ADO.NET 其中提供了一个 API 访问关系数据库,并表现在内存中的关系数据。此 API 由类如 SqlConnection、 SqlCommand、 SqlReader、 DataSet 和 DataTable,组成。使用这些类的问题是他们强制开发人员能够使用显式表、 记录和列等来表现,与现代语言如 C# 和 VB.NET 使用中面向对象的模式不相符。
现在,面向对象的在软件开发范例是使用模型,开发人员会导致大量的映射到其它的抽象特别关系数据库和 XML 的开销。结果是在编写相关代码是花费太多的时间。 LINQ 有助于我们提高工作效率。
但它不仅提高了生产力!它还会提高代码质量。编写乏味和脆弱模型类代码可能会导致隐伏缺陷软件或性能下降。
表 1.2 显示如何我们通常会访问.NET 程序中的数据库。通过发现存在的问题和与传统代码相比较,您将知道LINQ是非常优秀的。
表1.2.NET数据库类代码
using (SqlConnection connection = new SqlConnection("..."))
{
connection.Open();
SqlCommand command = connection.CreateCommand();
command.CommandText =
@"SELECT Name, Country
FROM Customers
WHERE City = @City";//SQL查询语句
command.Parameters.AddWithValue("@City", "Paris");
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string name = reader.GetString(0);//根据列获得获得相关参数
string country = reader.GetString(1);
...
}
}
}
只是开速浏览此代码,我们就可以列出该模型的一些限制:
■虽然要执行简单的任务但还是需要几个步骤和详细的代码。
■查询表示为带引号的字符串,这意味着他们绕过所有类型的编译时检查。如果该字符串不包含有效的 SQL 查询? 如果已在数据库中重命名一个列?就会出问题了。
■这同样适用于参数,并设置为结果,但并不严禁。是否是预料的类型的列?而且,是我们确保我们使用正确数目的参数?是否参数的名称,查询和参数声明之间一致?
■我们使用的类专用于 SQL Server,并且不能与另一台数据库服务器一起使用。当然,我们可以使用 DbConnection 及相关类来避免此问题,但这只会解决一半的问题。真正的问题是 SQL 有许多特定于提供商的方言和数据类型。我们编写不是一种类型的数据库使用的语法、语言也不一样。
存在其他的解决方案。我们可以使用代码生成器或可用的种几个的 对象映射工具之一。问题是这些工具不完善,完美的工具基本没有。为例如果它们旨在用于访问数据库,大多数情况下他们不能处理其他数据源如 XML 文档。