简单地说,LINQ是支持以类型安全方式查询数据的一系列语言扩展;它将在代号为“Orcas”的下一个版本Visual Studio中发布。待查询数据的形式可以是XML(LINQ到XML)、数据库(启用LINQ的ADO.NET,其中包括LINQ到SQL、LINQ到Dataset和LINQ到Entities)和对象(LINQ到Objects)等。LINQ体系结构如图1所示。
![]() |
| 图1:LINQ体系结构 |
让我们看一些代码。在即将发布的“Orcas”版 C# 中,LINQ 查询可能如下所示:
var overdrawnQuery = from account in db.Accounts |
当使用foreach遍历此查询的结果时,返回的每个元素都将包含一个余额小于0的帐户的名称和地址。
从以上示例中立即可以看出该语法类似于SQL。几年前,Anders Hejlsberg(C#的首席设计师)和Peter Golde曾考虑扩展C#以更好地集成数据查询。Peter时任C#编译器开发主管,当时正在研究扩展C#编译器的可能性,特别是支持可验证SQL之类特定于域的语言语法的加载项。另一方面,Anders则在设想更深入、更特定级别的集成。他当时正在构思一组“序列运算符”,能在实现IEnumerable的任何集合以及实现IQueryable的远程类型查询上运行。最终,序列运算符的构思获得了大多数支持,并且Anders于2004年初向比尔·盖茨的Thinkweek递交了一份关于本构思的文件。反馈对此给予了充分肯定。在设计初期,简单查询的语法如下所示:
sequence locals = customers.where(ZipCode == 98112); |
在此例中,Sequence是IEnumerable的别名;“where”一词是编译器能理解的一种特殊运算符。Where运算符的实现是一种接受predicate委托(即bool Pred(T item)形式的委托)的普通C#静态方法。本构思的目的是让编辑器具备与运算符有关的特殊知识。这样将允许编译器正确调用静态方法并创建代码,将委托与表达式联系起来。
假设上述示例是C#的理想查询语法。在没有任何语言扩展的情况下,该查询在C# 2.0中又会是什么样子?
IEnumerable locals = EnumerableExtensions.Where(customers,delegate(Customer c) |
这个代码惊人地冗长,而且更糟糕的是,需要非常仔细地研究才能找到相关的筛选器(ZipCode == 98112)。这只是一个简单的例子;试想一下,如果使用数个筛选器、投影等,要读懂代码该有多难。冗长的根源在于匿名方法所要求的语法。在理想的查询中,除了要计算的表达式,表达式不会提出任何要求。随后,编译器将尝试推断上下文;例如,ZipCode实际上引用了Customer上定义的ZipCode。如何解决这一问题?将特定运算符的知识硬编码到语言中并不能令语言设计团队满意,因此他们开始为匿名方法寻求替代语法。他们要求该语法应极其简练,但又不必比匿名方法当前所需的编译器要求更多的知识。最终,他们发明了lambda表达式。
Lambda表达式
Lambda表达式是一种语言功能,在许多方面类似于匿名方法。事实上,如果lambda表达式首先被引入语言,那么就不会有对匿名方法的需要了。这里的基本概念是可以将代码视为数据。在C# 1.0中,通常可以将字符串、整数、引用类型等传递给方法,以便方法对那些值进行操作。匿名方法和lambda表达式扩展了值的范围,以包含代码块。此概念常见于函数式编程中。
我们再借用以上示例,并用lambda表达式替换匿名方法:
IEnumerable locals =EnumerableExtensions.Where(customers, c => c.ZipCode == 91822); |
有几个需要注意的地方。对于初学者而言,lambda表达式简明扼要的原因有很多。首先,没有使用委托关键字来引入构造。取而代之的是一个新的运算符=>,通知编译器这不是正则表达式。其次,Customer类型是从使用中推断出来的。在此例中,Where方法的签名如下所示:
public static IEnumerable Where(IEnumerable items, Func<T, bool> predicate) |
编译器能够推断“c”是指客户,因为Where方法的第一个参数是IEnumerable,因此T事实上必须是Customer。利用这种知识,编译器还可验证Customer具有一个ZipCode成员。最后,没有指定的返回关键字。在语法形式中,返回成员被省略,但这只是为了语法便利。表达式的结果仍将视为返回值。
与匿名方法一样,Lambda表达式也支持变量捕获。例如,对于在lambda表达式主体内包含lambda表达式的方法,可以引用其参数或局部变量:
public IEnumerable LocalCusts(IEnumerable customers, int zipCode) |
最后,Lambda表达式支持更冗长的语法,允许您显式指定类型,以及执行多条语句。例如:
|
| 共4页: 1 [2] [3] [4] 下一页 | ||
|
|
|||
| · McWill、WiMAX、3G博弈 · 网管系统介绍 · 网络管理系统如何支撑I.. · CISSP认证成长之路 · 51CTO国庆充电专题之好.. · 网络技术经典基础教程 · 51CTO主编推荐经典专题 · RAID——磁盘阵列基础 |
· 充电计划之热门IT认证.. · 51CTO技术自测 挑战自.. · AMD Phenom三核处理器.. · 国际文档格式标准开战 · 2007年互联网大会 · 我是黑客我怕谁——讲.. · Solaris 10 配置管理 · Solaris基础知识入门 |
||
|
|||
| · Java基础教程 · VPN技术 · ARP攻击防范与解决方案 · SQL Server 2005全解 · SOA 面向服务架构 · SQL Server 2005全解 · Java编程开发手册 · RAID——磁盘阵列基础 |
· 三层交换技术专题 · SQL Server入门到精通 · Windows Server 2003企.. · Windows远程桌面应用 · C#技术开发指南 · VPN技术 · C#技术开发指南 · Solaris 10 配置管理 |
||
|
|||
| · ARP攻击防范与解决方案 · VPN技术 · SQL Server 2005全解 · Java基础教程 · SQL Server入门到精通 · SQL Server 2005全解 · SOA 面向服务架构 · Java编程开发手册 |
· C#技术开发指南 · 三层交换技术专题 · C#技术开发指南 · Windows远程桌面应用 · RAID——磁盘阵列基础 · Windows Server 2003企.. · 邮件服务器专题 · wimax技术与趋势 |
||
| ·DB2 Viper快速入门 ·DB2 9数据库的镜像分割与.. |
·将XML应用程序从DB2 8.x.. ·DB2 9中的pureXML:如何.. |
| ·服务器中的“傻瓜机”在.. ·盖茨也喜欢登录Youtube看.. |
· · |
| ·虚拟化改变操作系统的角.. ·拯救系统管理员 |
·美国选民:我为什么选布什 ·VMware公司中文命名挑战赛 |
| ·体验Windows Server 2008.. ·将超星图书转成PDF文档 |
·使用 Office Communicati.. ·VMware Workstation 6.01.. |
| · 华为、贝恩资本22亿美元.. · NGN:下一代网络 · 网络访问中断大排查 |
· 教你使用Anti ARP Sniff.. · 网络嗅探教程:使用Snif.. · 常见病毒手工清除方法大.. |
| · C++是垃圾语言?! · 2007年IT界七大抄袭事件 · Java实用开发全集 |
· 解析Ajax开发框架 走进A.. · 基于Google Maps与Ajax.. · 基于Google Maps与Ajax.. |
| · 热门 IT 培训认证官方资.. · Ubuntu 中文开源频道 · Solaris基础知识入门 |
· Google推出唯一硬件——.. · 硬盘之父获得诺贝尔物理.. · 理性面对四核服务器选购 |
| · 甲骨文Oracle 11g正式发.. · Oracle数据库开发之PL/S.. · Oracle数据库开发基础教.. |
· 硬盘之父获得诺贝尔物理.. · 存储2006,一个并购的大.. · IDC宣布浪潮蝉联存储市.. |