1 Win32(本机)数据访问技术
数据技术 | 发布时间 | 背景 |
DB-Library | 1989年 | SQL Server 1.0的诞生 |
Embedded SQL for C | 1989年 | SQL Server 1.0的诞生 |
ODBC | 1992年9月 | 为不同类型的数据库访问提供一个统一的接口 |
Data Access Objects | 1992年11月 | 面向对象技术的兴起及Visual Basic 3的发布 |
Remote Data Objects | 1995年8月 | Visual Basic 4的发布,取代DAO |
OLE DB | 1996年8月 | 提供一种适合某些开发风格的编程模型 |
ActiveX Data Object | 1996年10月 | 建立在 OLE DB上的更高级的对象抽象 |
1.1 DB-Library
1989年Microsoft发布SQL Server 1.0的同时,也发布了DB-Library,它是一个单一的编程式或调用级的API,通过它的150个函数,MS-DOS或OS/2控制台应用程序,Windows或OS/2 GUI应用程序能够访问数据来进行创建,检索,更新和删除操作。
1.2 Embedded SQL for C
一个预编译器,它允许SQL语句直接嵌入在源代码中,同时,这种方式也是LINQ的前身。
1.3 ODBC
1992年9月,Microsoft发布了开放数据库接通性规范(Open Database Connectivity specification,也即ODBC)。ODBC现在还在广泛使用,它是一个包含50个函数的调用级API,这个API通过驱动程序与许多底层数据库或类似数据库的存储器进行通信。ODBC在专用API之上建立了一个数据访问抽象层,它让应用程序以单一的方式访问各类数据源(从最古老的到最前沿的技术)。数据库提供商也能提供一个本机(也即,非中间件)ODBC驱动程序来获取更高的性能(如Microsoft提供的SQL Server驱动程序)。
当然,应用程序还是可以直接使用专用API;当应用程序需要操作来自不同提供商的数据库的数据库时,ODBC就提供了一种简单的访问方式----将应用程序与专用API分离了。
与ODBC相关的是ODBC”驱动程序管理器”库,当应用程序访问DBMS时,驱动程序管理器的作用是使用包含在驱动程序中的特定于DBMS的细节来解释应用程序发出的数据查询。数据库驱动程序是插在应用程序与DBMS之间的一个中间层(middle layer)。通过这种方式,数据查询被转换成DBMS理解的命令。
使用ODBC的基本条件是应用程序与DBMS必须是ODBC兼容的。换言之,应用程序必须能发出ODBC命令,DBMS必须能响应此命令。
开发数据库驱动程序的人必须实现将驱动程序附加到驱动程序管理库。
1.4 Data Access Objects
在面向对象技术兴起及Visual Basic 3发布的背景下,Microsoft于1992年11月创建了它的第一个面向对象的访问层---Data Acesss Objects。
1.5 Remote Data Objects
1995年8月,Microsoft发布了Visual Basic 4,随之,用Remote Data Objects(创建在ODBC之上的VB兼容的对象层)取代了Data Access Objects。
1.6 OLE(Object Linking and Embedding) DB
1996年8月,Microsoft发布了更通用(more generalized)的OLE DB技术,与ODBC相比,它创建了一个面向对象的访问层,以特定于数据存储的提供程序模式工作。
OLE DB现在还在广泛使用,与ODBC相比,它没有提升数据访问的抽象级别,只是简单地提供了一个编程模型以适合某些开发风格。当时,它的发布促成了许多类型数据存储的诞生,特别是表列数据[tabular data](如电子表格,文本文件)。从某种程度讲,OLE DB是ODBC的发展。
1.7 ActiveX Data Object
随着Internet的快速发展,人们认识到了web应用程序的重要性(与桌面客户应用程序相比)。然而,OLE DB是针对有指针的语言(如C,C++)开发的,这意味着像VBScript,JavaScript等脚本语言不能利用它。开发一种能让web应用程序访问各种数据存储的技术迫在眉睫。在此背景下,ActiveX Data Object于1996年10月诞生,它是建立上OLE DB之上的更高级别的对象抽象,可用于指针与非指针型语言。
截至1996年,有6 (DAO被RDO取代)种不同的Microsoft API用于数据访问:
1996年的选择 | SQL Server DBs | DBs w/ ODBC driver | DBs w/ OLE DB driver |
用C/C++写的应用程序 | DB-Library, ESQL/C, | ODBC | OLE DB, ADO |
用VB写的应用程序 | RDO | RDO | ADO |
Web应用程序 | ADO |
| ADO |
至此,其中的一些技术继续存在以支持开发人员需要写的各类应用程序。一些技术得到了发展,另一些更老的技术因为新技术的出现而退出历史舞台。当SQL Server 2005(引入了新的,更好的,直接的API---SQL Server Native Client)出现时,终止了对DB-Library的支持。LINQ的开发终止了ESQL for C的长期运行。
对RDO的支持直至Visual Basic 6,之后,Visual Basic升级为Visual Basic.NET,从而关注的焦点转向ADO.NET。
截至2010年9月,用于非托管代码的数据访问技术:
当前选择 | SQL Server DBs | DBs w/ ODBC driver | DBs w/ OLE DB driver |
用C/C++写的应用程序 | ODBC, OLE DB, ADO, SQL Native Client | ODBC | OLD DB, ADO |
Web应用程序 | ADO, PHP Driver, | 用于 ODBC 的 OLE DB 提供程序 (MSDASQL) | ADO |
2 .NET框架版本
版本 | 版本号 | 发布时间 | Visual Studio | 默认安装的Windows | 备注 |
1.0 | 1.0.3705.0 | 2002-02-13 | Visual Studio .NET |
| SP3 |
1.1 | 1.1.4322.573 | 2003-04-24 | Visual Studio .NET 2003 | Windows Server 2003 | SP1 |
2.0 | 2.0.50727.42 | 2005-11-07 | Visual Studio 2005 | Windows Server 2003 R2 | SP3 |
3.0 | 3.0.4506.30 | 2006-11-06 |
| Windows Vista Windows Server 2008 | SP2 |
3.5 | 3.5.21022.8 | 2007-11-19 | Visual Studio 2008 | Windows 7 Windows Server 2008 R2 | SP1 |
4.0 | 4.0.30319.1 | 2010-04-12 | Visual Studio 2010 |
|
|
3 当今的数据开发之一:直接的数据访问
.NET框架(2002年2月发布1.0版,2003年4月发布1.1版)的横空出世改变了应用程序的开发方式,但是没有改变应用程序访问数据的基本要求。
数据访问的主要类包括SqlConnection,SqlCommand,DataReader,DataSet及DataTable,这些类一起组成了ADO.NET的核心。
与它的前身—ADO类似,ADO.NET通过一个抽象层(隐藏了底层存储技术的细节)来工作,这层就是ADO.NET数据提供程序。Microsoft为SQL Server提供了一个本机提供程序,也提供了用于OLEDB,ODBC
的提供程序。而且,ADO.NET支持对XML源的透明访问(ADO做不到)。
.NET 2002/2003中的ADO.NET
值得注意的是,ADO.NET的基本数据访问编程模式(即,查询)与之前的技术基本相同:
[a] 打开数据库连接;
[b] 在数据库中执行查询;
[c] 获取数据结果集;
[d] 处理结果;
[e] 释放结果;
[f] 关闭连接;
换言之,当API和其它细节变化时,代码的基本结构仍然保持不变。这不是坏事,因为这种编程模式完全符合数据库的的基本目的:提问题,然后获取答案。实事上,可以推断不管什么时候出现一种新的通用开发环境(类似DotNET框架),都会产生一种新的并且遵循这种模式的数据访问技术。同时,ADO.NET将继续是Microsoft数据访问的核心方式。
3.1 Language-Integrated Query (LINQ)
LINQ首次于2007年11月在.NET Framework 3.5中引入,它是ESQL for C的发展产物:将查询直接嵌入在编程语言本身的结构中。很显明,LINQ是一种比它的前身更高级的解决方案:
l LINQ能在任何支持它的.NET语言(像C#,Visual Basic.NET)中使用它;
l LINQ加入了很多现代的性能优化;
l LINQ能对任意数据源进行操作(也即查询,更新);
数据源可以是内存中的CLR对象,XML,数据库,ADO.NET数据集及其它实现了IEnumerable或Iqueryable的类。如下图:
2007年11月引入的LINQ(包含LINQ to Objects,LINQ to XML,LINQ to DataSet,LINQ to SQL)
不仅有Microsoft提供的”LINQ to XYZ”实现,也有许多三方的实现,这些包括LINQ to Flickr,LINQ to Amazon,LINQ to CSV,LINQ to MAPI及LINQ to Twitter。简言之,如果某些东西看来起是可查询的数据,你就可以在其实现Iqueryable,然后使用LINQ来访问它。
然而,我们要看到,在LINQ实现了简单,强大的查询机制(特别是对DataSet,SQL Server数据库的查询上)的同时,它并没有从本质上改变应用程序看待关系数据的方式。迄今为止,所有操作关系数据的技术(DB-Library,ESQL for C,ODBC,OLEDB,ADO,ADO.NET及LINQ)无一不是直接操作数据库表的关系结构。
当数据库和应用程序都比较简单时,这种方式能很好地工作。然而,当数据库与应用程序都变得越来越复杂时,应用程序看待数据的方式(“概念”或”对象”模型)与数据库中数据的结构化方式(“存储”或”关系”模型)之间的矛盾也越来越突出。以一个制造商的订购系统为例,数据存储在多个关联的表中,然而,程序员只想使用一个单一的,概念性的”Order”实体,不想在订购相关的查询中使用复杂的”JOIN”。(这就是所谓的”对象关系阻抗失配”。)
由于这个原因,程序员常常自己实现映射层以创建单一的概念实体。这样的一层提供了一个单一的”Order”对象,这个对象包含检索,更新等类似方法,这些方法在内部实现了必要的数据库级查询(使用Order对象与底层数据库表交换数据)。
简言之,映射层简单地将应用程序与数据库的具体逻辑结构分开了,这在目前的项目中是很常见的模式。不过,这种层维护和实现起来都很繁琐。
3.2 ADO.NET Entity Framework
.NET框架3.5SP1(包含实体框架)于2008年8月发布后,映射层难以实现与维护的状况有了改变,2010年4月.NET框架4.0发布后,对映射层又有了很大改进。正如实体框架的名字所暗示的那样,实体框架自动从现有数据库生成一个.NET映射层。另外,它还支持使用LINQ对最终实体进行查询(LINQ to Entities)。由于实体框架是建立在ADO.NET之上的,所以它直接利用ADO.NET提供程序。
我们可以使用Visual Studio中的设计器来创建概念与关系。它会自动创建一个默认的映射。
直到2010年9月,Microsoft最新的数据访问技术如下:
实体框架的第一个版本,它自动创建概念映射。编译时使用实体数据模型生成映射层类。
4 托管代码,非托管代码及本机代码是什么?
4.1 托管代码(managed code)
托管代码是Visual Basic.NET,C#,F#或其它第三方针对.NET运行时的编译器创建的代码。托管代码编译成中间语言(IL),而不是可以直接运行在计算机上的机器代码。IL保存在一个称为程序集(assembly)的文件里,此文件包含元数据,它描述了代码中的类,方法及特性(如安全需求)。程序集是.NET世界中的一站式部署单元。你可以将它复制到另一台服务器来将其部署在那里,复制常常是部署唯一需要做的。
托管代码运行在公共语言运行时中。运行时为运行中的代码提供许多服务。实际执行过程中,运行时首先加载并检查程序集以确保IL是正常的。然后,当调用方法时,运行时就将其编译成程序集所在机器能执行的机器码,并缓存这个机器码以供下次调用时使用(这就是所谓的即时编译)。
程序集运行时,运行时将继续为其提供服务,如安全,内存管理,线程等。应用程序总是受运行时管理。
4.2 非托管代码(unmanaged code)
非托管代码就是你在Visual Studio .NET 2002发布之前写的代码。Visual Basic 6,Visual C++ 6,可能还在你硬盘上的C编译器都产生非托管代码。非托管代码直接编译成机器码,可以运行在编译它的机器上,也可以运行在有相同或接近相同芯片的其它机器上。它不会从不可见的运行时那里获得诸如安全,内存管理等服务。它直接从操作系统获得这些服务。值得注意的是,它必须显式向操作系统发出服务请求,常常通过调用Windows SDK中的一个API来实现。距离当前较近的非托管应用程序可以通过调用COM来获得操作系统服务。
与Visual Studio中的其它语言不同,Visual C++能创建非托管程序。这可能会造成一些混淆:你创建一个托管的C++应用程序时,生成的产品是一个扩展名为exe的IL程序集。你创建一个MFC应用程序时,生成的产品是一个Windows可执行文件(本机代码),扩展名也是exe。然而,这两个文件的内部布局完全不同。你可以使用中间语言反汇编程序(ildasm)来查看程序集及其元数据。当你打开非托管的exe文件时,会提示不能打开。
4.3 本机代码(native code)
术语"本机代码"有两种使用环境。许多人将其视为非托管代码的同义词;这个术语的另一种使用是用来描述JIT编译器的输出--运行在运行时中的机器代码。它被管理,但它不是IL,它是机器码。从这个意义上讲,不能简单假设"本机=非托管"。