<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>
导 读:.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的优良特性,并且更易于使用。
相关推荐
本书可以使您的专业知识不再停留在基础阶段,它会引领您深入研究ADO.NET 2.0的重要编程主题。本书作为全面的技术内幕参考书,提供了专家指南、实用指令及用Visual c#和Visual Basic编写的代码示例,帮助您深入掌握...
Ado.Net 数据库开发 教程,非常适合开发者深入研究!
一共两份,一份初级入门,一份深入研究,附带超星阅读器,不能打开PDF文档的,就安装一下就行了
ADO.NET应用程序和基础数据源之间的交互基于一个具有双向信道的双体系结构。您可以使用各个特定于提供程序的命令或批处理更新过程来访问数据源,以读取和写入行。在这两种情况下,数据访问都会产生完全双向绑定,并...
本文主要介绍了ADO.NET的基本特点,并且使用的一些代码展示了在ADO.NET中如何建立数据库连接,发送查询命令及使用DataReader对象...为此,本网站将在即将推出的《ADO.NET深入研究》中对DateSets对象进行深入的探讨。
ADO.NET 2.0 大批量数据操作和多个动态的结果集 ADO.NET 2.0 异步处理 在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+...
ADO.NET 与 XML:双剑合壁,威力强大.doc ASP.NET HTTP 运行时.doc ASP.NET ViewState 初探.doc ASP.NET Web 方法中的 XmlElement 参数的功能.d ASP.NET 中 Cookie 的基本知识.doc ASP.NET 页面对象模型.doc ...
该系统采用ADO.net技术可以容纳具有复杂关系的数据,不再依赖于数据库链接;而且其开发模式有助于减少软件的维护费用,提高软件的可移植性和可伸缩性,提高网络性能,甚至有助于提高软件开发人员的生产力和缩短开发...
该系统采用ADO.net技术可以容纳具有复杂关系的数据,不再依赖于数据库链接;而且其开发模式有助于减少软件的维护费用,提高软件的可移植性和可伸缩性,提高网络性能,甚至有助于提高软件开发人员的生产力和缩短开发...
论文还深入剖析了ASP.NET中的关键技术,如MVC模式、ADO.NET数据库访问技术等,帮助读者更好地理解和掌握ASP.NET的精髓。 **源代码部分**: 源代码基于Visual Studio平台开发,采用C#作为编程语言。代码结构清晰、...
本页内容调试器条件编译跟踪和TraceSwitch断言TraceListener—Listeners正在侦听BugslayerTraceListener的用法和实现更多新功能小结因为Microsoft已经发布了VisualStudio....,所以许多读者已经开始深入研究.NET...
该系统采用ADO.NET技术可以容纳具有复杂关系的 数据,不再依赖于数据库链接;而且其开发模式有助于减少软件的维护费用,提高 软件的可移植性和可伸缩性,提高网络性能,甚至有助于提高软件开发人员的生产 力和缩短...
本文理论部分主要针对数据库设计技术、存储过程技术、ADO.NET技术以及用SQL Server .NET Framework 数据提供程序访问SQLserver2000数据库技术这四个方面进行了研究和探讨。 图书馆管理信息系统的每一行代码都是...
13.7.4 LINQ to Entities,ADO.NET Entity Framework的LINQ接口 383 13.8 小结 384 第14章 使用LINQ操作DataSet 385 14.1 LINQ to DataSet概览 385 14.2 DataSet回顾 386 14.2.1 DataSet使用场景及功能...
数据库设计报告 课题:超市会员管理系统 专业:通信工程 学号: 姓名: 小组成员: 指导老师: 完成日期:2013/7/1 摘要 本会员超市会员管理系统实际的业务流程为背景而...其次,在ASP.NET中利 用.NET框架中的ADO.NET的
器 对客流分析系统功能的融合存在一定的限制 本文通过对 ASP NET web 应用程序中的动态报表进行了深入研究 提出了一种, 。 , . 动态 Web 客户端报表模型构建 使用 Report Viewer Control 和 ADO NET 对报表的底层...