ADO.NET深入研究(2)[特别推荐]

ado

导 读:.NET 在数据存取方面做了很大的调整。在.NET 框架下,数据存取是由ADO.NET来完成的,这是一个ADO的改进和完善版本。它最显著的变化是其完全基于XML。而对于从事ADO开发的人员来说,Recordset对象的消失也令他们感到惊奇。
--------------------------------------------------------------------------------

翻译整理:.net技术网(www.51dotnet.com)slash
原文出处:http://www.dnjonline.com/articles/essentials/iss22_essentials.html

表4显示了DataSet 中现有的数据。可以发现现在有两种数据类型,同时SCHEMA 也做了相应的调整来描述这两种数据类型。

请注意我们现在并没有做创建一个内连接或外连接,而是类似于用SHAPE 语言用两个单独的表创建了一个分级的Recordset对象。当然你也可以创建连接,这在DataSet中表现为一个表。

ADO开发者在操作Recordset 对象的时候,需要知道他们到底需要一个客户端还是服务器端的光标。MoveFirst 或是 AbsolutePosition之类的操作,在服务器端光标的情况下将消耗很大的服务器资源,但在客户端光标的情况下,确是高效和有力的工具。两类光标存在着巨大的差异。一个客户端光标的Recordset 对象事实上更类似于一个高性能的数组,而不是一一种序列化的存取结构。

与之相对,DataSet 始终是'客户端的',并且可以发挥'高性能数组'存取模型的最高效率。在Recordset 中有字段集合,但对于一个Recordset 对象,却没有相应的集合。而DataSet中的所有表都有一个列和一个行的集合,你可以使用简单的随机存取技术来操作它们,表5显示了在ADO.NET 中操作DataSet的对象模型。

通过循环的方式你可以对DataTable中的每一行进行操作,然而我在下一个例子中采用了另一种方法:DataTable 的 Select 方法。这是一个重载方法,从本质上来说,它相当于结合了Recordset的FILTER 和 SORT 属性。SELECT 方法返回一个以DataRow对象为元素的数组--能够利用标准的数组的方法对它处理。需要注意的是所有这些过程是在你程序的缓存中进行的,DataSet 已经和数据源完全的断开了。

下面的示例代码向DataSet中填充两个数据表(第二个表没有使用 WHERE 子句)然后用SELECT 方法从'Authors'返回一个数组,并利用该结果创建一个动态的下拉列表。

Dim dc As New ADODataSetCommand( _
"select au_id, au_fname," & _
" au_lname from authors", strConnect)
Dim ds As New DataSet()

' Declare an array of DataRows
Dim dr() As DataRow
Dim i As Integer

dc.FillDataSet(ds, "Authors")
dc = New ADODataSetCommand( _
"select * from titleauthor", strConnect)
dc.FillDataSet(ds, "Titles")

dr = ds.Tables("Authors").Select( _
"au_lname >= 'R'", "au_lname ASC")

For i = 0 To UBound(dr)
listbox1.Items.Add( _
CStr(dr(i)("au_fname")) & " " _
& CStr(dr(i)("au_lname")))
Next

在这里,SELECT 语句返回所有的行,其中的 last name 的打头字母在 'R'之前,并且对这些行进行了分类,'Titles'表在这里被忽略了

表之间的联系

如果你没有利用SHAPE LANGUAGE 进行过工作,你很可能只是创建一个拥有一个数据表的 DataSet 并对其进行操作,就象Recordset 对象一样。当你一旦向DataSet 中加入了多个表,你会希望在它们之间建立关联以便于操作。在下面的代码中,假定以与上例完全相同的方法创建了一个名为DS的DataSet 对象:

Dim dr() As DataRow
Dim drChildren() As DataRow
Dim dl As DataRelation
Dim i, j As Integer

dl = New DataRelation("AuthorTitles", _
ds.Tables("Authors").Columns("au_id"), _
ds.Tables("Titles").Columns("au_id"))
ds.Relations.Add(dl)

dr = ds.Tables("Authors").Select( _
"au_lname >= 'R'", "au_lname ASC")

For i = 0 To UBound(dr)
listbox1.Items.Add( _
CStr(dr(i)("au_fname")) & " " _
& CStr(dr(i)("au_lname")))
drChildren = dr(i).GetChildRows(dl)
For j = 0 To UBound(drChildren)
listbox1.Items.Add(" " & _
CStr(drChildren(j)("title_id")))
Next
Next

DataSetCommands

表 6:
使用list box显示两个表的一多关系

这段代码在'Authors' 表和 'Titles'表之间建立了一个父子关系的关联,这是通过创建一个DataRelation对象(命名为dl)并将它加入DataSet实现的。关联指定 au_id 为关键字段,通过对子表('Titles')中 au_id 的匹配来得到父表中每一行的子行。在ADO 数据筛选的SHAPE 语言中是,这是通过 RELATE 语句来实现的。

当你指定了父表中的行时,你可以利用这种关联。你可以通过GetChildRows方法得到所有子表中所有相关的行,当然这里的关联关系是由你来决定的。DataRelations 使得创建一个master-detail程序变的非常简单。上面的代码的显示结果见表6。

下面我们来了解一下ADODataSetCommand对象以及与它功能相似的SQLDataSetCommand对象。我们已经了解了它们三个主要功能中的一个,就是通过使用命令字符串和一个连接号向DataSet 对象中加入数据。下面对另外两个主要功能进行讨论,首先是更新(updating)。

在传统的ADO中,一个客户端的 Recordset 对象通过SQL 语句来进行更新。在这里SQL 模拟开放式锁定,因此更新得以被返回到数据库。这是一个灵活的机制,但有两个缺点:一、自动生成的SQL语句不易更改,因此假如你写一些高效率的存储过程,将会比直接使用SQL 语句迅速的多。二、这是第一个问题的延续。当需要更新的数据源无法理解ANSI-SQL的时候,你就无法使用客户端的Recordset了。象Active Directory, Exchange 2000以及 Indexing Services这些兼容ADO 的数据源,它们不兼容ANSI 的标准。因此你如果想通过ADO对它们进行更新,你就只能使用服务器端的光标了。

在ADO.NET 中这些问题被解决了。第一种方法,DataSet 与数据源完全断开,ADODataSetCommand作为一个独立的实体与数据源进行交互。更新完全由ADODataSetCommand进行,而DataSet则被完全隔离。

第二中方法,ADODataSetCommand将更新的SQL语句作为一种公开的属性,这样你可以轻松的替换SQL 语句,或者是存储过程。更为出色的是,如果你想使用存储过程,Visual Studio.NET 将为你生成,在下一部分我们可以看到具体的应用。

最后是关于数据表映射功能。数据的使用者不需要得到这样一个数据表:列以'au_fname' 和 'au_lname'命名。不仅是不美观的问题,更重要的是这样会把数据库的结构暴露出来了,数据映射允许你在DataSet 中替换列的名字,如果需要,可以为不同的用户提供不同的数据表映射,下面我将介绍如何利用Visual Studio.NET ,在图形化的界面下创建数据更新的代码。

简单的可视化设计

Visual Studio.NET 为 Windows Forms, Web Forms, Web Services, Components and XML Schemas的设计提供了图形化的设计工具。设计者只需要从工具条上的控件拖动到工作区域 就可以了。在这里,工作区域将与最终用户看到的界面有很大区别。

当你将一个非可视的对象如ADODataSetCommand拖动进来时,它将被显示在设计视图中,但用户将无法看到这个对象。其他的数据控件也是这样。

表7显示了一个VB.NET的项目,这个项目有一个窗体,上面有一个DataGrid控件、一个CommandButton以及ADODataSetCommand控件,在这里你可以象在Visual Studio 6中一样来处理ADODataSetCommand:在可视化的界面中你可以利用向导来建立ADODataSetCommand的连接字符串,命令字符串;在与数据库的接口上,你可以选择自动生成SQL语句,选择已有的存储过程,或是创建一个新的存储过程。

表8显示了向导的最终结果,你可以给你创建的存储过程命名,或者只是预览一下,然后将之存为文件以便以后修改。

如果你不想利用存储过程,你也可以直接使用SQL语句,你还可以在属性面板上修改这些语句。你还可以做的工作包括给对列进行简单化的命名,以便你今后能够方便的使用。具体的操作可以参看表9的对话框。

在完成了以上的工作后,应用程序的编写变的相对很轻松了,下面是DATAGRID的绑定的代码:

Me.ADODataSetCommand1.FillDataSet(dsAuthors)
Me.DataGrid1.DataSource = dsauthors

ADODataSetCommand1成为窗体Me的一个属性,它将dsAuthors表装入一个DataSet 对象,接着设置DataGrid的DataSource属性为dsAuthors。最后是编写CommandButton的CLICK 事件:

Me.ADODataSetCommand1.Update(dsAuthors)

UPDATE 事件将根据对dsAuthors的修改对数据源进行更新(具体的UPDATE 方法在存储过程中已经被设定)。这与ADO 中断开连接的RecordsetS对象的批量更新很相似,但效率更高。可以在表10中看到最终完成的应用程序,它的列名已经被替换为新的列名。

表10: 运行结果

类型化的DataSet

对于许多开发者来说,他们已经习惯了使用ADO 的 Recordset 对象的,象使用字段(fields)而不是使用属性(properties),这样做有它的优势,但也有很多缺陷。首先,与属性不同,字段并不是强类型的,它不为IntelliSense技术(自动提醒语法、参数和对象属性)所支持。另外,因为不是强类型,所以你无法为它添加自定义的方法或是属性,这意味着当你需要把一个Recordset 对象的功能完全封装起来的时候,你会遇到许多限制。

与之相对,因为.NET 平台支持继承,所以你可以创建DataSet 对象的子类,并向其中添加新的功能。这就是具有类型的 DataSet,它基本上没有什么使用范围的限制,所有DataSet 在.NET 中内建的特性都将被支持,包括绑定,和XML DOM 的内部操作。为了创建这样一个具有类型的 DataSet 对象,你所需要的只是一个XSD 格式的 XML SCHEMA。

当你基于一个DataSetCommand 上创建具有类型的 DataSet 的时候,你甚至可以让Visual Studio.NET 来创建这样一个 XML SCHEMA,所有的工作只是鼠标在'Generate DataSet'菜单上的轻轻一点(见表7)。在这里使用的XML SCHEMA与表2中的是一样的(除非你对数据表的结构做了改动)

在后面的例子中我将使用我创建的具有类型的AuthorsDataSet 对象来代替DataSet 对象。AuthorsDataSet中的所有表和列都将是它的属性,因此所写出的代码将更易于查看,而强类型将更不易出错,同时还可以利用IntelliSense技术。表11显示了类型化的DataSet 的编程界面,注意IntelliSense菜单也被显示出来了。

表11中我们可以看到在AuthorsDataSet被创建之后,同时还创建了authorsSelectTable(继承于DataTable),authorsSelectRow(继承于DataRow),以及所有的列的类(继承于DataColumn),由此,我们可以看到继承对.NET 的重要意义。

FindByAuthor_ID方法自动被添加到authorsSelectTable类中,列属性被自动添加到authorsSelectRow类中,所有的类的代码都是非隐藏的而且易于扩展。如果你已经习惯了使用断开连接的(disconnected)或是虚拟的(fabricated)Recordset 对象,那么转向ADO.NET 使用具有类型的 DataSet 对象是一个很好的选择。

ADO 到 ADO.NET 是一个革命性的发展,在所有的.NET Framework领域中,许多基本的组件可以被重写,因为不用受到二进制兼容性的强制性约束所以可以对所有类型的组件的接口进行重写和改善,而ADO.NET 只是其中一例。

在经过了几个星期的使用后,我认为 ADO.NET 与ADO 相比是一个更完善的模型,我非常满意它对ADO所做的改进。虽然某种程度上讲,对于开发者来说,需要学习一种新的对象模型,但我仍建议开发者向.NET转移。ADO.NET 继承了ADO的优良特性,并且更易于使用。

时间: 2024-11-01 17:05:22

ADO.NET深入研究(2)[特别推荐]的相关文章

ADO.NET深入研究(1)[特别推荐]

ado 导 读:.NET 在数据存取方面做了很大的调整.在.NET 框架下,数据存取是由ADO.NET来完成的,这是一个ADO的改进和完善版本.它最显著的变化是其完全基于XML.而对于从事ADO开发的人员来说,Recordset对象的消失也令他们感到惊奇. -------------------------------------------------------------------------------- 翻译整理:.net技术网(www.51dotnet.com)slash原文出处:

ADO.NET快速起步 [特别推荐]

ado 导 读:本文主要介绍了ADO.NET的基本特点,并且使用的一些代码展示了在ADO.NET中如何建立数据库连接,发送查询命令及使用DataReader对象快速浏览数据集方式. --------------------------------------------------------------------------------翻译整理:.net技术网(www.51dotnet.com)郜飞 小狮子英文版 :http://www.itpeople.com.cn/tech/tech-n

推荐、特别推荐、头条等引导性内链的运用

随着搜索引挚对于站内优化的越来越重视,并且搜索引挚给予排名的主要参考标准是用户体验,可以说现在内链在SEO中的作用举足轻重,通过百度百科可以看到把站内优化做到极致也一样可以有效的提高并且稳定排名.对于站内优化的细节,比如导航.结构.内容.界面等等,对于一个网站来说,把推荐.特别推荐.头条.热点这些引导性的内链方式做好,无疑于引导用户.留住用户,增加用户的访问时间,从页进一步增强用户体验度.今天,石家庄牛牛网带大家从这些常用的引导性内链方式来具体分析一下: 一 引导性内链的分析 推荐.特别推荐.头

阿里云机器学习8月特别推荐

阿里云机器学习·简介 阿里云机器学习平台是一套基于MaxCompute(阿里云分布式计算引擎)的数据挖掘.建模.预测的工具.它提供算法开发.分享.模型训练.部署.监控等一站式算法服务,用户可以通过可视化的操作界面来操作整个实验流程,同时也支持命令,让用户通过命令行来操作实验. 8月特别推荐 众所周知,在很多业务场景的大数据处理中,经常需要挖掘海量数据背后的商业价值.阿里云数加平台推出机器学习开发工具大大提高了数据挖掘的效率,然而缺乏数据.缺乏场景成为大多数用户学习阿里云数加机器学习平台的难题.没

网易云阅读WP8版获微软特别推荐

7月23日, 网易云阅读WP8版凭借出色表现获得微软官方推荐,被Windows Phone官网特别推荐应用榜单收录前列. 网易云阅读WP8版界面一览     Windows Phone官网特别推荐应用榜单是微软官方为用户推荐优质应用的展示入口,得以上榜的应用在其领域均有过人之处.作为第 一款资讯/书籍全能型移动阅读应用,网易云阅读目前已收录10万多本 各类优质书籍和互联网域内的各类优质精品内容源,并能提供一站式服务,支持对RSS.微博.博客和QQ空间的订阅,为用户贴心打造个性阅读平台.除了良好的

外媒《投资在中国:12位专家的选择》特别推荐网易和盛大

5月21日消息,据国外媒体报道,StockAdvisors网站编辑史蒂芬-哈尔彭(Steven Halpern)近日在其发表的文章<投资在中国:12位专家的选择>一文中列举出了中国12大行业中值得投资的股票,在网游业特别推荐了网易和盛大. 随着全球经济危机袭来,中国再一次证明自己是全世界最具抵抗力.最坚韧的市场.全球专家Nicholas Vardy表示,虽然美国市场也出现回暖,但相比之下中国市场更为火热.种种迹象表明中国政府的刺激政策正在结出果实.中国网游行业的发展尤其引人注目,而其中又属网易

ado.net详细研究(一)

ado 最近阅读了wrox的高效掌握 ADO.NET,有所感触,希望与大家分享.第一次写文章,不好请谅解. 第一篇:ADO.NET的概念 ADO.NET中间包含以下常见类: · Connection · Command · DataAdapter · DataReader · DataSet 1 Connection类数据库Connection类提供与数据库的连接..net里面有OleDbConnection类和SqlConnection类,分别针对不同的数据库.SqlConnection针对s

ado.net详细研究(二) —— DataReader(一)

ado 这次我们详细研究DataReader.我个人最喜欢的就是DataReader,虽然它不如DataSet强大,但是在很多情况下我们须要的是灵活的读取数据而不是大量的在内存里面缓存数据.比如在网络上每个用户都缓存大量的dataset,这很可能导致服务器内存不足.另外dataReader尤其适合读取大量的数据,因为它不在内存中缓存数据. 由于下面的讨论都设计到数据库操作,我们虚拟一个小项目:个人通讯录(单用户),这意味着我们须要一个contract的数据库,包含admin和fridend: a

ADO.NET详细研究(五)--DataReader终结篇

ado 这一次我们将把DataReader了结,同时我们提到的有些技巧与DataReader无关但是是很基本的也很有用的技巧.一,参数化查询在上一篇文章发表以后不少网友提意见说代码不规范,没有对sql使用参数,这确实是很大一个漏洞,所以我在这里首先谈一下参数化查询问题.使用参数化查询的好处:可以防止sql注入式攻击,提高程序执行效率.针对sql server .net data Provider,我们可以使用@作为前缀标记的参数.比如:const string connStr = "Data s