何谓 LINQ
程序语言随着时间演进,一再沉淀经验与抽象后,以简练直观的语法解决具有共通特征的各式问题。Visual Studio 2008(程序代码名称为 Orcas)、C# 3.0 与 VB.NET 9.0 后将支持新的语法 Language Integrated Query(LINQ),想一体解决多样的资料存取。它是由 Anders Hejlsberg 所主导。Anders 曾打造了 Turbo Pascal、Delphi、Visual J++、C# 等叫好叫座的产品,单凭这位杀手应用创造者的眼光,LINQ 就不可小觑。
LINQ 是一系列语言延伸模块,以型别安全的方式支持数据查询。期待隔绝各种数据的特性,不管是各厂家数据库的 SQL 方言,或是 XML 的 DOM、XQuery 或 XPath,抑或是对象集合的属性存取。以共通的方式完成数据操作,如:挑选、比对、排序、汇总…等等。期待减轻程序开发人员学习操作各种数据的负荷。
LINQ 藉由各语言编译程序将内嵌的 LINQ 语法转译成原本的 C# 或 VB.NET 程序代码,并呼叫相关的底层模块以实体维护数据。最后编译成与 .NET Framework 2.0 CLR 兼容的 IL,所以 CLR 本身并未增加与 LINQ 相关的模块,但 .NET Framework、Visual Studio 整合开发环境和程序语言需要增加相关功能和语法。
就笔者自己的感觉,LINQ 有以下的好处:
l 简化大量的细节运作,将如何(how)取得数据换成要操作什么(what)数据:这隐含存取优化交由专家来做,如 DB 引擎优化存取数据。
l 透过IEnumerable<t></t>一致性地存取各种数据,并在查询语法中互相整合:如 File System、操作系统的 process、Registry、对象集合、XML、DB...,所用的皆是对象,大家的属性都是数据。换句话说,数据对象化,对象数据化,存取二者的语法与语意相同。
l 平行运算:若要处理大量数据,程序设计师不容易撰写 for 循环还包含平行运算。但 LINQ 转译成 C# 或 VB.NET 的程序代码时,可以平行运算的方式处理大量数据。
l 撰写数据对象存取的过程中,可以 IntelliSense 和强型别检查:相较于以往 ADO.NET 加上 SQL 语法,LINQ 比 typed dataset 直观易懂,且应用更为广泛。
就笔者与许多朋友聊到 LINQ 时,最多的询问便是「未来是否不需要学 SQL 了?」个人认为,短时间不可能,LINQ 或许会减轻程序设计师对 SQL 的倚赖,但 LINQ 不会取代 SQL。它们各有一片天,LINQ 是程序设计师讲的数据对象语言,SQL 是数据库管理师对数据库引擎讲的语言,LINQ 是从应用程序处理数据的角度出发,但 SQL 关乎着整体数据库服务器有效且安全地活着的每一个细节。
而紧接的问题通常是:「将数据以对象来包装,透过 entity 类别间接存取数据,那是否会有效率问题?」这笔者无法回答,尚待真实世界来证明。
LINQ 范例
你可以在 C# 中直接内嵌如下的语法:取得在 Customer 对象集合中,每个 Customer 的属性 Country 值为 USA,按照 City 属性由大到小排序,传回以 CompanyName 和 City 两个属性的字符串值所建立的新对象之集合:
var matchCustomers = from c in db.Customers
where c.Country == "USA"
orderby c.City descending
select new { c.CompanyName, c.City };
这句 LINQ 语法经由 C# 编译程序解析,传回实做 IEnumerable<anonymous type></anonymous>接口的对象给 matchCustomers 变量。而在查询语法中,呼叫了 where、orderby、select 等延伸方法(Extension Methods)。并定义匿名方法(Anonymous Methods)的委派(delegate);要求 where 方法比较 Customers 集合中 Customer 对象的 Country 属性值为 USA。换句话说,自动将 c.Country == "USA" 转成 bool Pred<t>(T item) </t>形式的委派。最后透过 select 延伸方法搭配对象初始化表达式,回传匿名型别(Anonymous Type)对象的集合。
若不采用 LINQ 写法,上述语法也可以写成如下的方式:
var matchCustomers = db.Customers.Where(c => c.Country == "USA").OrderByDescending(c => c.City).Select(c => new { c.CompanyName, c.City });
哇,想我修习 .NET 数年,竟不知所云!?在此介绍一本入门书:「Introducing Microsoft LINQ」,Microsoft Press 出版。它让你了解以往的 C# 和 VB.NET 各版本如何渐进地增加功能,最后演变出 LINQ 语法。
书籍内容
本书结构短小,仅六章加上一个附录。
第一章针对 LINQ 做总体概观介绍,初读此章时,觉得过于唐突,比照下载的完整范例程序代码还是不知所云,满头问号。待看完本书其他章节后,再回过头看第一章,这回看懂了J
没有任何进步是独立完成的,因此本书第二、三章介绍为了支持 LINQ,或应该说若你要了解 LINQ 的运作原理,必须先熟悉 C# 与 VB.NET 的相关功能,约略表列如下:
l C# 2.0 提供的泛型(Generic)、匿名方法,与改良的委派和 Enumerators 与 Yield。
l C# 3.0 提供的 Local Type Inference、Lambda 表达式(Lambda Expressions)、延伸方法、隐含型别化局部变量(var)、匿名型别,和改良的对象初始化表达式(Object Initialization Expressions)。
VB.NET 9.0 与 LINQ 语法相关的项目和前述 C# 相似,但少了 yield 关键词和匿名方法[1],多了对 XML 语法的支持和 Relaxed Keyword。
本书第四章介绍 LINQ 的语法结构,以及各种数据集合的运算,如连结、排序、过滤、群组、汇总..等 .NET Framework 预设为 LINQ 所提供的多种延伸方法。
第五章介绍 LINQ to ADO.NET 的特征,这又分为 LINQ to SQL、LINQ to DataSet、LINQ to Entities ,本章简述这三部分的建置与对应的 LINQ 语法:
l LINQ to SQL 透过 Orcas 的「LINQ to SQL File」模板产生出类别实体,以对应 SQL Server 数据库内的某些数据表及其关联,或是呼叫预存程序、函数等数据库对象的方法后,撰写数据处理的语法变得直观易懂。搭配交易,以属性和方法来新增、修改、删除、查询数据对象。
l LINQ to DataSet:由于 DataSet 可以视作内存中的小型数据库,而赋予 DataSet 数据的方式也很多样化,因此当 DataSet 有数据后,仍透过 LINQ 如同对一般数据库的存取。
l Orcas 内建了产生 Entity Data Model(EDM) 的精灵,将数据存取对象的操作与数据实体储存机制隔绝开来。LINQ 仍以相似的方式存取对象化的数据实体。此部分的相关信息可参考本书的附录。
第六章解释何谓 LINQ to XML。由于 LINQ to XML API 尝试简化 XML 的相关技术,所以建置了一整组 X 开头的类别,让你以直观的对象架构存取 XML 的各种节点,而不需要透过 W3C XML DOM 的繁复方式。本章除了说明这些 X 开头的类别与以往 DOM 各对象方法之对应外,也阐述了如何透过 LINQ 维护 XML 数据。
在附录中解释了 ADO.NET Entity Framework 的架构,以及 Orcas 如何产生该架构下的三种档案:
l Conceptual Schema Definition Language(CSDL):用来描述程序代码所依据的数据定义。
l Storage Schema Definition Language(SSDL):用来描述实体数据储存区,如 SQL Server 对数据库内各对象的定义。
l Mapping Schema Language(MSL):用来联系对应 CSDL 和 SSDL,因此 CSDL 与 SSDL 可以多对多对应,也就是数据操作与数据储存能够分开。
Orcas 参照 CSDL 会产生出代表数据的实体(entity)对象之 C# 程序代码,再经由 SSDL 和 MSL 结合到数据储存的实体,如 SQL Server。当透过 LINQ 操作 ADO.NET Entity 时,可轻易完成数据维护与交易管理。
本书是为熟悉 C# 的程序设计师介绍 LINQ 语法,因此全书的文字内容并没有完整的可执行范例[2],且未与 ASP.NET 或 Windows Form 等用户接口技术整合。但对于 LINQ 的基本技术介绍得还算完整。由于只有 217 页,逐页读完,也就对 LINQ 了然于胸J。若仅想熟悉 C# 或 VB.NET 二者之一,还可以在第二、三两章中择一,需要阅读的分量就更少了。
但若不熟悉 C#,则你需要很大的耐心,先了解本文上述所表列 C# 的各项功能,并反复阅读本书,才能渐渐融会贯通。
最后,若你要购买本书,先有两点考虑:
l LINQ 还处于 Beta,明年推出的正式版可能仍有变化。
l 相对于内容分量,本书的价格偏于昂贵。
也因如此,它在 Amazon 的评价只有两颗星。或许,它仅适合买书不考虑成本,以及对于新知充满好奇的人。
本书仅是 LINQ 的入门介绍,对于实际使用 LINQ 到日用习惯的数据操作,如与控件做双向数据系结(DataBinding)以维护数据库内数据、弹性地动态组 SQL 语法等,并未明确地交代。期待这一部分随着 Orcas 步入正式版会有简单且完整的解法。
相关阅读
最后,笔者列出些相关的资源以延伸阅读:
Anders Hejlsberg (C# 首席设计师)对 LINQ 定位的说明与实际亲手示范其用法:
l http://channel9.msdn.com/showpost.aspx?postid=114680
MSDN 上介绍 LINQ 的文件:该篇专栏可几近取代本书的第二章。
l http://msdn.microsoft.com/msdnmag/issues/07/06/csharp30/default.aspx?loc=zx
作者为本书所建置的网站,上有当作试阅的第一章,以及可下载的范例程序代码:
[1] VB.NET 9.0 虽未个别支持 Anonymous Method 的宣告与使用,但 lambda expression 和 LINQ 实则需要 Anonymous Method 的运行架构。因此 VB.NET 9.0 编译程序在底层解释与编译前述二者的语法时,已经采用了 Anonymous Method。
[2] 本书没有随附范例程序代码光盘,仅可从网站下载。但若你想要执行那些范例,最好先从 MSDN 下载并安装 Orcas 的 Beta 版。才能顺利执行范例程序代码。