您的位置:首页 > 数据库

数据库-ADONET-使用强类型DataSet

2008-12-02 14:46 375 查看
使用强类型DataSet对象

使用ADONET访问DataSet内容的方式,与使用ADO和DAO的Recordset对象具有类似的编程格式。

l ADONET和VBNET

txtCompanyName.Text=ds.Tables(“Customers”).Row(0)(“CompanyName”)

l ADO、DAP和VB经典方式

txtCompanyName.Text=rs.Fields(“CompayName”).Value

为了更容易的编写数据访问代码,ADONET引入了强类型DataSet对象。现在可以如下编码

txtCompanyName.Text=ds.Customers(0).CompanyName

可以把强类型DataSet认作是一个带有类的DataSet,它是继承自DataSet类的一个子类,并且还包含基于你所指定的架构的属性和方法,同时该类还包含用于DataTable对象及DataRow对象的其他类,这些类可以更高效的编写数据访问代码。

1 创建强类型DataSet对象

如何创建一个强类型DataSet?

有两种办法:其一,使用代码编写并使用NET框架的SDK命令行工具;其二,使用VSNET开发环境。

1.1 使用命令行工具编写代码

NET框架SDK有一个名为XML架构定义工具的命令行使用工具,它能根据XML架构文件(.xsd)生成类文件。

使用这个使用工具,结合DataSet的WriteXmlSchema方法,可以将一个Dataset解析成强类型DataSet类。

1.1.1 使用DataSet对象的WriteXmlSchema方法

XSD文件包含DataSet的架构信息(表、列、约束和关系)。

使用DataSet对象的WriteXmlSchema方法能够创建该文件。

WriteXmlSchema方法,其重载版本能接受,一个Stream对象、一个TextWriter对象、一个XmlWrite对象或字符串表示的文件名。

n 代码演示:用Northwind数据库的Customers和Orders表的列创建一个DataSet,在将DataSet的架构写入文件之前,为两表添加DataRelation。

Dim strConn,strSql as string

strConn=”Providor=SQLOLEDB;Data Source=...;Initial Catalog=Northwind;

Trused_Connection=Yes”

Dim cn As New oleDbConnection(strConn)

strSql=”select CustomerID,CompanyName,ContactName,Phone from Customers”

Dim daCustomers as New oleDBDataAdapter(strSql,cn)

strSql=”select OrderID,CustomerID,EmployeeID,OrderID from Orders”

Dim daOrders as New OleDbDataAdapter(strSql,cn)

Dim ds as new DataSet()

Ds.DataSetName=”Chapter9”

Cn.Open()

daCustomers.FillSchema(ds,SchemaType.Source,”Customers”)

daOrders.FillSchema(ds,SchemaType.Source,”Orders”)

cn.Close()

ds.Relations.Add(“CustomersOrders”,ds.Tables(“Customers”).Columns(“CustomerID”),

ds.Tables(“Orders”).Columns(“CustomerID”))

ds.WriteXmlSchema(“C:"Chapter9.xsd”

1.1.2 使用XML架构定义工具

XML架构定义工具,实际上是指位于Bin目录下的XSD.exe文件,它可以根据XML架构文件生成类文件,还能从Dll文件和EXE文件创建XML架构

l 示例

前面的代码将DataSet架构保存到Chapter9.xsd文件之中,现在在这个基础上使用XML架构定义工具生成一个类文件。

1.开始菜单,NET Framework v2.0,SDK命令提示,

2.对于VBNET输入,XSD Chapter9.xsd /d /l:VB

3.对于C#输入,XSD Chapter9.xsd /d

第一个参数指明XSD文件的路径

第二个参数,指明要创建的类由DataSet派生

第三个参数,指明输出文件语言(默认是C#)

使用时,只需要将新类文件加入“解决方案”,并创建新DataSet类的实例:

Dim ds As New Chapter9()

【类的名字】是基于产生XSD文件的DataSet的名字得来的。

1.2 简单的方法(使用IDE)

创建过程描述:

首先,创建一个所选语言的新Windows应用程序,将OleDBDataAdapter添加到窗体,在适配器向导中,将OleDBDataAdapter指向Northwind数据库,并输入以下语句:

Select CustomerID,CompanyName,ContactName,Phone from Customers

Select OrderID,CustomerID,EmployeeID,OrderDate from Orders

在设计器右键菜单中选择“生成数据集”,输入名字“Chapter9”。

下面设计DataRelation,在“解决方案”窗口,双击架构文件,右键单击Orders表,在菜单中选择“添加”|“新关系”,编辑好关系后确定。

显示类文件

在解决方案窗口顶部,工具栏中选择“显示所有文件”按钮即可。

DataSet(Chapter9.xsd)的架构文件会有两个与该架构文件相关联的文件。第一个是Chapter9.vb或者Chapter9.cs的强类型DataSet类文件;第二个关联文件扩展名为.xsx,它是包含了对XML架构设计器中DataSet的布局进行设置的文本文件。

实际上,该类文件包含许多类。由DataSet派生出来的是主类,这个类公开了两个DataTable对象,分别对应Customers和Orders,而两个DataTable都公开了Item属性,用来返回有DataRow派生出来的子类。

2 使用强类型DataSet对象

强类型DataSet对象简化了开发过程;使编写代码来访问和修改DataSet的内容更加容易。

2.1 添加行

DataSet中的DataTable,每个类都有两种途径——将一个新行添加到DataTable中。

其一:使用New《表名》Row方法,在返回的强类型DataRow中设置列内容,然后调用

Add《表名》Row添加到表。

Dim ds As New Chapter9()

Dim tblCustomers As Chapter9.CustomersDataTable = ds.Customers

Dim rowCustomer As Chapter9.CustomersRow

rowCustomer = tblCustomers.NewCustomersRow

rowCustomer.CustomerID = "ABCDE"

rowCustomer.CompanyName = "ABCDE有限公司"

rowCustomer.ContactName = "ABCED联系人"

rowCustomer.Phone = "(800) 555-1212"

tblCustomers.AddCustomersRow(rowCustomer)

或者这样写:

Dim rowCustomer as DataRow=tblCustomers.NewRow()

rowCustomer(“CustomerID”)=”ABCED”

...

tblCustomers.Row.Add(rowCustomer)

强类型DataRow的优越性之一就是,在IDE中可以直接支持语句完成(Statement Completion)功能。

但是,尽管在VB5开始就已经支持语句完成,但是如果在VB6和ADO2.x代码中输入错误的列名,那么要到运行时才会发现该错误,强类型DataSet和语句完成都无法消除开发时出现的此种问题。

强类型的Add《表名》Row,这个方法也有重载版本。

Dim ds as New Chapter9()

Dim tblCustomers As Chapter9.CustomersDataTable=ds.Customers

tblCustomers.AddCustomersRow(“ABCDE”,”NewCompany”,”NewCantact”,”555-1212”)

上句可替换为

tblCustomers.Rows.Add(new Object(){“ABCDE”,”New Company”,”New Contact”,”555-1212”})

IntelliSense和语句完成是在编写代码时,给人印象最深的特性之一。

2.2 查找行

对于标准非类型化DataSet,可以“根据主键值”,利用DataTable.Rows集合的Find方法,查找特定行。

但是,有时候Find方法会造成混淆,尤其是主键是组合键的情形,例如Northwind数据库中的Order Details表,其主键是OrderID和ProductID。

如果DataTable有一个定义过的主键,那么强类型的DataSet的每一个DataTable都公开自己的Find方法。给强类型DataSet中使用组合键作为主键的表编写查找代码很容易。

daOrderDetails.Fill(Chapter91, "Order Details")

DataGridView1.DataSource = Chapter91.Order_Details

Dim tblDetails As Chapter9.Order_DetailsDataTable = Chapter91.Order_Details

Dim rowDetails As Chapter9.Order_DetailsRow

rowDetails = tblDetails.FindByOrderIDProductID(10248, 59)

If rowDetails Is Nothing Then

MsgBox("行没找到")

Else

MsgBox("找到行!" & vbCrLf & "其订单ID为:" & rowDetails.OrderID & " - " & "产品ID为:" & rowDetails.ProductID)

End If

2.3 编辑行

对强类型DataSet中的行进行编辑的过程与编辑标准数据集中的行类似,

可供选择的方法有BeginEdit、EndEdit和CancelEdit

也可以使用强类型DataRow的属性来访问DataRow列的值。

2.4 处理空数据

可以使用DataRow对象的IsNull函数对空值进行检验;使用System.Convert.DBNull可以给列指派一个空值。

强类型数据集对空值处理是:

每一个强类型的DataRow中,各列都可以:校验列是否包含空值(Is<列名>Null);设置列值为空(Set<列名>Null)

'首先添加数据

daCustomers.Fill(Chapter91, "Customers")

Dim tblCustomers As Chapter9.CustomersDataTable = Chapter91.Customers

DataGridView1.DataSource = tblCustomers

Dim rowCustomer As Chapter9.CustomersRow

rowCustomer = tblCustomers.FindByCustomerID("AROUT")

If rowCustomer Is Nothing Then

MsgBox("没找到")

Exit Sub

End If

'检验公司名空值

If rowCustomer.IsCompanyNameNull() Then

MsgBox("第一次检验- 公司名为空值")

Else

MsgBox("第一次检验- 公司名为: " & rowCustomer.CompanyName)

End If

'设置空值

rowCustomer.SetCompanyNameNull()

'检验公司名空值

If rowCustomer.IsCompanyNameNull() Then

MsgBox("第次检验- 公司名为空值")

Else

MsgBox("第次检验- 公司名为: " & rowCustomer.CompanyName)

End If

2.5 处理层次数据

DataRow对象中,公开的两种通过层次数据进行查找的方法是:GetChildRows和GetParentRow。这两种方法需要提供引用的DataRelation的名字或者其对象本身。

在强类型DataSet中,如果存在DataRelation,则不需要指定DataRelation或其名称,XML架构定义工具将自动添加该方法。

具体的说:在强类型数据集中,给Customers表和Orders表建立关联,将更改保存到xsd文件,xml架构定义工具就会为Customers表添加GetOrdersRows方法到强类型DataRow类中,并为Orders表将GetCustomersRows方法添加到强类型DataRow类中。

Dim ds As Chapter9 = Chapter91

daCustomers.Fill(ds)

daOrders.Fill(ds)

Dim rowCustomer As Chapter9.CustomersRow

Dim rowOrder As Chapter9.OrdersRow

For Each rowCustomer In ds.Customers

ListBox1.Items.Add("客户" & rowCustomer.CompanyName & "的订单")

For Each rowOrder In rowCustomer.GetOrdersRows()

ListBox1.Items.Add(vbTab & "订单编号- " & rowOrder.OrderID & vbTab & "下定日期- " & rowOrder.OrderDate)

Next

Next

‘上面代码对应的非强类型数据集代码是

Dim rowCustomer,rowOrder As DataRow

For Each rowCustomer In ds.Tables(“Customers”).Rows

Console.WriteLine(“Orders for “ & rowCustomer(“CompanyName”))

For Each rowOrder In rowCustomer.GetChildRows(“CustomersOrders”)

...

...

2.6 其他的DataSet、DataTable和DataRow特性

XML架构定义工具生成的类是:DataSet的派生类、DataTable的派生类、DataRow的派生类

因此,可以将它们看做是其非类型化的相应类。

例如:强类型DataSet没有可读写XML数据和架构信息的方法,但是由于派生关系,仍然公开了ReadXML和WriteXml等方法。

对于像用DataAdapter获取数据或提交更改之类的任务,可将强类型DataSet等同于普通DataSet对待。

3 何时使用强类型DataSet

3.1 软件组件

简单的组件,通常比那些提供一大串功能的组件运行的快。

强类型的DataSet,明显比非类型化的DataSet公开的功能要强大。但是,如果不使用附加配件的话,构造简单的,会更好。

3.2 设计时的优势

强类型DataSet在设计时的优势:编写访问代码很容易(这要感谢IDE的语句完成和智能感知IntelliSense功能)。

因为,强类型DataSet的初始化代码中,包含了创建架构和必要的DataTable、DataColumn、DataRelation以及Constraint所需的代码。

使用非类型化DataSet,有三种“将架构信息添加到DataSet的方法”:

1. 自己编写代码;

2. 使用DataSet对象的ReadXmlSchema方法,从XSD文件中加载架构;

3. 使用DataAdapter对象的FillSchema方法

如果正在建立一个使用数据绑定的Windows或web应用程序,那么,使用强类型数据集可以,更容易的在设计时绑定组件。为什么?因为,强类型DataSet包含自己的架构信息,所以能够给一列绑定控件。

创建多层应用程序时,可以通过强类型DataSet,将一个引用添加到一个类库,或将其添加到一个返回强类型DataSet的Web服务是,项目会复制XSD文件和强类型DataSet的类文件,客户端应用程序就能利用强类型DataSet在设计时的优势。

3.3 运行时优势

强类型DataSet对象的运行时含义是什么?它们如何影响应用程序的性能?

使用强类型DataSet对象,不仅易于编写代码,而且,代码还能提高应用程序的性能。

强类型代码,运行速度几乎是非类型化代码的,两倍。

强类型DataSet是如何提高性能的?DataRow对象允许通过提供列的名称、列的序号或DataColumn对象本身来访问列的内容。使用真正DataColumn对象的代码性能最好;使用列的名称编写代码最容易,但是性能最差。

由XML架构定义工具生成的代码兼顾了两方面的优点。编写的代码容易维护,并且自动生成的代码使用了DataColumn对象。

任何程序员无法编写的代码,对于强类型DataSet对象来说,也同样无法生成。

实际上,所有强类型DataSet能实现的功能,都可以编码实现。

比如:要想以访问强类型DataSet那样的性能,访问一个非类型化DataSet的内容,就要避免在集合中执行基于字符串的查找,而使用基于索引的查找,或维护非类型化DataSet中的列引用。

修改代码:在非类型化DataSet中使用适当的DataColumn对象访问行的内容,并使用适当的类型转换代码,结果是新改进的访问比访问强类型DataSet的代码快5%到10%。

由于创建、填充和访问强类型DataSet需要更多的时间,所以这里非类型化DataSet比强类型DataSet性能上稍微好一点。

3.4 其他注意事项

决定使用强类型DataSet,还需要考虑其他一些问题。

3.4.1 进行结构更改

如果,需要通过添加或修改DataColumn对象来更改强类型DataSet对象的结构,则,必须重新生成强类型DataSet对象,特别是在生成一个多层应用程序(并且中间层返回强类型DataSet)时。

如果重新生成了强类型DataSet(中间层要返回的),就需要在对中间层的引用进行刷新之后,重新生成客户端程序。

但是,如果准备改变服务器返回的数据结构时,不论是否使用强类型DataSet,都需要改变访问该结构的客户端代码。

3.4.2 转换DataSet对象

由于强类型DataSet继承自标准DataSet,因此,通过“一个非类型化DataSet接口访问强类型DataSet的代码”是正确的。

比如:

Dim dsStrong as New Chapter9()

Dim dsUntyped as DataSet

dsUntyped=Ctype(dsStrong,DataSet)

但是,还要特别注意这个问题:

Dim dsStrong1,dsStrong2 as Chapter9

Dim dsUntyped as DataSet

‘下面是能成功的代码

Strong1=new Chapter9()

dsUntyped=Ctype(dsStrong1,DataSet)

dsStrong2=Ctype(dsUntyped,Chapter9)

‘下面的代码则会抛出异常

dsUntyped=New DataSet()

dsStrong2=Ctype(dsUntyped,Chapter9)

如果,有一个非类型化的DataSet,想使用强类型DataSet访问它,该怎么办?

(这里说的是,原有DataSet是非典型的DataSet)

可以使用强类型DataSet的Merge方法,从非类型化DataSet中导入数据。

Dim dsStrong as New Chapter9()

Dim dsUntyped as New DataSet()

dsStrong.Merge(dsUntyped)

Merge方法,有助于在两个不同的“强类型DataSet”实例之间,转移数据。

如果对WriteXml和ReadXml方法的调用,包含Xml架构的话,还可以使用WriteXml和ReadXml方法在两个不同的强类型DataSet类实例之间转移数据。

3.4.3 强类型DataSet对象的非类型化特性

假如,应用程序使用强类型DataSet,并且想要将DataSet送回中间层服务器,然后将更改提交给数据库的话,可以使用强类型DataSet对象提供的GetChanges方法,来创建一个只包含被修改的行的新DataSet,并且,GetChanges方法返回非类型化DataSet。

能否将GetChanges方法返回的非类型化DataSet,再转化成强类型DataSet呢?当然是可以的。

Dim dsStrongAllRows as New Chapter9()

‘对强类型进行填充,并修改一些行,此处代码省略

Dim dsUntyped as DataSet

dsUntyped=dsStrongAllRows.GetChanges()

Dim dsStrongModifiedRows as Chapter9

dsStrongModifiedRows=Ctype(dsUntyped,Chapter9)

强类型DataSet,还有其他返回非类型化数据的方法,比如,Select方法,返回DataRow对象的一个数组,不能将返回数组转化为强类型DataSet对象的数组,但是可以将单个DataRow对象转化为相应的强类型DataRow。

相似的规则也可用于DataView,虽然不能直接通过强类型DataSet类访问它的内容,但是能够将通过DataRowView的Row属性返回的DataRow转化为强类型的。

Dim dsStrong as New Chapter9()

‘对此对象填充数据,和修改部分行,代码略

Dim vueCustomers as New DataView(dsStrong.Customers)

Dim rowCustomer as Chapter9.CustomersRow

rowCustomer=Ctype(vueCustomers(0).Row,Chapter9.CustomersRow)

3.5 方法的选择

什么样的选择才是正确的?

强类型DataSet,能够更快的创建应用程序,能够更容易的编写高效的代码。

但是它们不提供最好的性能。

如果结合非类型化DataSet和智能代码来使用,就可以创建运行更快的程序。

选择,完全取决于程序的需要。

如果程序的性能不是最优先的考虑事项,应该使用非类型化DataSet对象;但是如果牺牲一部分性能来换取开发时间是值得的,那么就应该考虑使用强类型DataSet。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐