以下对象用于表达数据集中的关系:
DataSet - 在内存中表示数据,可以包含多个可与 DataRelation 对象相关的 DataTable 对象。有关详细信息,请参阅 Introduction to Datasets。
DataTable - 表示一个完整的数据表。数据表的架构是由构成该表的 DataColumnCollection 定义的。当两个数据表相关时,DataRelation 对象使用每个表中的 DataColumn 来关联数据。有关详细信息,请参阅 Creating and Using DataTables。
DataRelation - 连接多个表,以便浏览相关表中的记录。访问相关记录时,DataRelation 对象被传递给 GetChildRows 或 GetParentRow 方法。DataRelation 对象确定所要查询的相关表,以便返回与 GetChildRows 或 GetParentRow 方法调用相关联的相关数据。有关详细信息,请参阅 Introduction to DataRelation Objects。
DataRow - 表示数据的一个单独的记录。用于返回相关数据的 GetChildRows 方法和 GetParentRow 方法是 DataRow 对象的成员。
DataColumn - 表示一个单独的字段,结合在一起时将定义 DataTable 的架构。当两个数据表相关时,DataRelation 对象使用每个表中的数据列来关联数据。
创建应用程序
本节将建立这一演练的起点。随后的步骤将创建数据连接、数据适配器和包含相关表的数据集,以及几个选择和显示数据的控件。
创建新的 Windows 应用程序
从 File(文件)菜单中,指向 New(新建),并选择 Project(项目)。将显示 New Project(新建项目)对话框。
在 Project Types(项目类型)窗格中,根据您需要的编程语言,选择 Visual Basic Projects(Visual Basic 项目)或 Visual C# Projects(Visual C# 项目)。
在 Templates(模板)窗格中,选择 Windows Application(Windows 应用程序),并将其命名为 DataRelationExample,然后单击 OK(确定)。
DataRelationExample 项目将添加到 Solution Explorer(解决方案资源管理器)中。
连接到数据库
此连接允许您与 Visual Studio® 集成开发环境 (IDE) 中的数据源进行通讯。
连接到 Server Explorer(服务器资源管理器)中的罗斯文示例数据库
在 Server Explorer(服务器资源管理器)中,建立连接到罗斯文示例数据库的数据连接。有关详细信息,请参阅 Adding New Data Connections in Server Explorer。
在 Server Explorer(服务器资源管理器)中展开罗斯文数据连接,直到可以看到所有的表。
创建数据适配器和连接
此步骤创建用于在应用程序和数据源之间连接和交换数据的连接和数据适配器。
创建数据适配器和连接
将“客户”表从 Server Explorer(服务器资源管理器)中拖到窗体上。组件栏中将显示连接和数据适配器。
选择 Connection(连接)并将 Name 属性设置为 dcNorthwind。
选择数据适配器并将 Name 属性设置为 daCustomers。
将“订单”表从 Server Explorer(服务器资源管理器)中拖到窗体上。组件栏中将显示第二个数据适配器。
选择新的数据适配器并将 Name 属性设置为 daOrders。
生成数据集
使用刚刚添加到窗体上的数据适配器生成包含客户表和订单表的数据集。
生成将包含相关数据表的数据集
从 Data(数据)菜单中,选择 Generate Dataset(生成数据集)。将显示 Generate Dataset(生成数据集)对话框。
提示:将光标移到窗体上即可使用 Data(数据)菜单。
单击 New(新建)并将数据集命名为 dsNorthwind。
选择客户表和订单表。
选择 Add this dataset to the designer(将此数据集添加到设计器)复选框,然后单击 OK(确定)。
Solution Explorer(解决方案资源管理器)的项目中将添加一个名为 dsNorthwind.xsd 的文件,并且组件栏中将显示该数据集的一个实例。
创建关系
生成数据集并不能自动创建数据集中各表之间的关系。关系可以通过编程创建,也可以使用 XML Designer(XML 设计器)直观地创建。本文使用 XML Designer(XML 设计器)。
创建客户表和订单表之间的关系
在 Solution Explorer(解决方案资源管理器)中,双击 dsNorthwind.xsd 文件。文件将在 XML Designer(XML 设计器)中打开。
从工具栏的 XML Schema(XML 架构)选项卡中,将 Relation(关系)拖到订单表上。
在 Edit Relation(编辑关系)对话框中,设置以下属性:元素 设置
Name CustomersOrders
Parent Customers
Child Orders
Key Fields CustomerID
Foreign Key Fields CustomerID
单击 OK(确定)以创建关系并关闭对话框。
从 File(文件)菜单中,选择 Save All(全部保存)以保存该项目。
显示数据
此应用程序使用组合框、列表框和 RTF 文本框来选择和显示数据。
添加选择和显示数据的控件
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1(.cs 或 .vb,取决于应用程序的语言),然后从快捷菜单中选择 View Designer(视图设计器)。
在窗体的左半部,添加一个 ListBox 控件,并将其 Name 属性设置为 lbOrders。
在窗体的右半部,添加一个 RichTextBox 控件,并将其 Name 属性设置为 rtbDetails。
在列表框的上方,添加一个 ComboBox 控件,并将其 Name 属性设置为 cbCustomers。
保存项目。
图 1:建议的窗体控件布局
现在,可以开始向应用程序添加功能了。
设置显示公司名称的组合框
选择组合框 (cbCustomers) 并设置以下属性:属性 设置
DataSource DsNorthwind1
DisplayMember Customers.CompanyName
ValueMember Customers.CustomerID
用数据填充表
要用数据填充表,必须为应用程序添加代码。
在数据集 (dsNorthwind1) 中的客户表和订单表中填充数据
双击窗体上的一块空白区域,为 Form1_Load 事件创建事件处理程序。
添加以下代码:
' Visual Basic
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
' 关闭数据集中的约束。
DsNorthwind1.EnforceConstraints = False
' 用数据填充表。
daOrders.Fill(DsNorthwind1)
daCustomers.Fill(DsNorthwind1)
' 重新开启约束。
DsNorthwind1.EnforceConstraints = True
End Sub
// C#
private void Form1_Load(object sender, System.EventArgs e)
{
// 关闭数据集中的约束。
dsNorthwind1.EnforceConstraints = false
// 用数据填充表。
daOrders.Fill(dsNorthwind1)
daCustomers.Fill(dsNorthwind1)
// 重新开启约束。
dsNorthwind1.EnforceConstraints = true
}
保存项目。
按 F5 键运行该应用程序。现在组合框中包含一个公司名称列表。
关闭窗体。
在两个表中浏览相关记录
这里简要介绍一下如何在数据集中构成一对多关系的两个表之间访问数据。在选择一个数据行之后,可以通过调用 GetChildRows 或 GetParentRow 方法并向该数据行传递适当的数据关系来返回其相关记录。
注意:GetChildRows 方法将以 DataRow 对象数组的形式返回数据,而 GetParentRow 方法只返回一个单个的数据行。
要演示这一功能,需要给应用程序添加一些代码,以返回组合框中选定客户的所有订单(子行)。更改组合框中的选定客户会引发 ComboBox.SelectedIndexChanged 事件,列表框中将填充该选定客户的每个订单的订单 ID。
您可以根据组合框中选定的客户,调用 GetChildRows 方法。订单表中的所有相关记录都将分配给名为 draOrders 的数据行数组。
注意:下一节将添加在列表框中显示相关订单列表的功能。为确认数组中确实包含相关的记录,数组的长度(即选定客户的订单总数)将显示为窗体的标题。
创建获取选定客户的订单的事件处理程序
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1 并从快捷菜单中选择 View Designer(视图设计器)。
双击组合框为 SelectedIndexChanged 事件创建事件处理程序。
添加以下代码:
' Visual Basic
Private Sub cbCustomers_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles cbCustomers.SelectedIndexChanged
' 声明一个用来保存选定客户的客户 ID 的字符串。
Dim SelectedCustomerID As String
SelectedCustomerID = cbCustomers.SelectedValue.ToString()
' 声明一个用来保存选定客户的记录的数据行。
Dim drSelectedCustomer As DataRow
drSelectedCustomer = _
DsNorthwind1.Customers.FindByCustomerID _
(SelectedCustomerID)
' 声明一个用来保存相关记录的数据行数组。
Dim draOrders As DataRow()
draOrders = drSelectedCustomer.GetChildRows("CustomersOrders")
' 在窗体标题中显示数组的长度(订单数)
' 和客户 ID。
Me.Text = draOrders.Length.ToString() &" 订单所有者 " &_
SelectedCustomerID
End Sub
// C#
private void cbCustomers_SelectedIndexChanged
(object sender, System.EventArgs e)
{
// 声明一个用来保存选定客户的客户 ID 的字符串。
String SelectedCustomerID
SelectedCustomerID = cbCustomers.SelectedValue.ToString()
// 声明一个用来保存选定客户的记录的数据行。
DataRow drSelectedCustomer
drSelectedCustomer =
dsNorthwind1.Customers.FindByCustomerID(SelectedCustomerID)
// 声明一个用来保存相关记录的数据行数组。
DataRow[] draOrders
draOrders = drSelectedCustomer.GetChildRows("CustomersOrders")
// 在窗体标题中显示数组的长度(订单数)
// 和客户 ID。
this.Text = draOrders.Length.ToString() +
" 订单所有者 " + SelectedCustomerID
}
保存项目。
运行应用程序。
选择另一个客户,并检查窗体标题。将显示选定客户的订单总数及其客户 ID。
关闭窗体。
显示相关记录
现在您已经有了选定客户的相关记录(存储在数据行数组中),您可以显示它们以便与用户进行交互。应用程序将逐一访问 GetChildRows 方法返回的数据行数组中的数据,并将每个相关记录的“订单 ID”作为单独的项添加到列表框中。
注意:虽然此示例将逐一访问相关数据行数组中的数据,但列表框可能已经使用属性窗口,通过 DataSource 属性、DataMember 属性和 ValueMember 属性被绑定到相关的记录。
在列表框中显示相关记录
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1 并从快捷菜单中选择 View Code(查看代码)。
在前面步骤中创建的组合框的 SelectedIndexChanged 事件处理程序中,将以下代码添加到处理程序中已有代码之下:
' Visual Basic
' 当更改选定客户时,清除订单列表。
lbOrders.Items.Clear()
rtbDetails.Text = ""
' 将每个相关订单的订单 ID 添加到列表框中。
Dim drOrder As DataRow
For Each drOrder In draOrders
lbOrders.Items.Add(drOrder("OrderID"))
Next
// C#
// 当更改选定客户时,清除订单列表。
lbOrders.Items.Clear()
rtbDetails.Text = ""
// 将每个相关订单的订单 ID 添加到列表框中。
foreach(DataRow drOrder in draOrders)
{
lbOrders.Items.Add(drOrder["OrderID"])
}
保存项目。
运行应用程序。
列表框中将显示订单列表。在组合框中选择另一个客户,订单列表将被更新。
关闭窗体。
在三个或更多表中浏览相关记录
浏览三个或更多表与处理两个表一样简单。要了解如何处理两个以上的表,请将订单明细表和产品表添加到
dsNorthwind
数据集中。在列表框中选定一个订单后,该订单的详细信息即显示在 RTF 文本框中。
为了满足约束规则,您需要删除现有的数据关系,将来再重新创建。
暂时删除 dsNorthwind 数据集中的 DataRelation
在 Solution Explorer(解决方案资源管理器)中,双击 dsNorthwind.xsd 以在 XML Designer(XML 设计器)中打开它。
选择现有的 CustomersOrders 关系并将其删除。
保存项目。
现在您需要将另外两个表添加到现有数据集中,并创建新的 DataRelation 对象以将所有表连在一起。
将订单明细表和产品表添加到 dsNorthwind 数据集中
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1 并从快捷菜单中选择 View Designer(视图设计器)。
将“订单明细”表从 Server Explorer(服务器资源管理器)中拖到窗体上。组件栏中将显示一个新的数据适配器。
选择该新的数据适配器并将其 Name 属性设置为 daOrderDetails。
将“产品”表从 Server Explorer(服务器资源管理器)中拖到窗体上。组件栏中将显示一个新的数据适配器。
选择该新的数据适配器并将其 Name 属性设置为 daProducts。
新表只是被添加到了窗体上,因此每次添加额外的表时,都必须重新生成数据集。
重新生成 dsNorthwind 数据集
从 Data(数据)菜单中,选择 Generate Dataset(生成数据集)。
提示:将光标移到窗体上即可使用 Data(数据)菜单。
单击 Existing(现有),然后选择 dsNorthwind 数据集。
选择所有四个表(客户表、订单表、订单明细表和产品表)。
清除 Add this dataset to the designer(将此数据集添加到设计器)复选框,然后单击 OK(确定)。将生成带有附加表的数据集。
注意:如果出现一个对话框,其中说明“The file has been modified outside of the source editor. Do you want to reload it?”(文件已在源编辑器之外被修改。是否要重新加载?),请单击 Yes(是)。
请记住,生成数据集并不能自动创建数据集中各表之间的关系。
创建关系
在 Solution Explorer(解决方案资源管理器)中,双击 dsNorthwind.xsd 文件。文件将在 XML Designer(XML 设计器)中打开。
从工具栏的 XML Schema(XML 架构)选项卡中,将 Relation(关系)拖到订单表上。
在 Edit Relation(编辑关系)对话框中,设置以下属性:元素 设置
Name CustomersOrders
Parent Customers
Child Orders
Key Fields CustomerID
Foreign Key Fields CustomerID
单击 OK(确定)以创建关系并关闭对话框。
从工具栏的 XML Schema(XML 架构)选项卡中,将 Relation(关系)拖到订单明细表上。
在 Edit Relation(编辑关系)对话框中,设置以下属性:元素 设置
Name OrdersOrderDetails
Parent Orders
Child OrderDetails
Key Fields OrderID
Foreign Key Fields OrderID
单击 OK(确定)以创建关系并关闭对话框。
从工具栏的 XML Schema(XML 架构)选项卡中,将 Relation(关系)拖到订单明细表上。
在 Edit Relation(编辑关系)对话框中,设置以下属性:元素 设置
Name ProductsOrderDetails
Parent Products
Child OrderDetails
Key Fields ProductID
Foreign Key Fields ProductID
单击 OK(确定)以创建关系并关闭对话框。
保存项目。
订单明细表和产品表已被添加到数据集中,但是您仍需要添加代码,以便在运行时用数据来填充它们。
用数据填充表
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1 并从快捷菜单中选择 View Code(查看代码)。
在 Form1_Load 事件处理程序中,将以下代码添加到注释“
用数据填充表
”与
daOrders.Fill(dsNorthwind1)
行之间:
' Visual Basic
daOrderDetails.Fill(dsNorthwind1)
daProducts.Fill(dsNorthwind1)
// C#
daOrderDetails.Fill(dsNorthwind1)
daProducts.Fill(dsNorthwind1)
用数据填充 RTF 文本框
现在您要为项目添加代码,以便在列表框中选定某个订单时,可以在 RTF 文本框中显示所有订单明细。
以下代码将基于列表框中的选定订单调用 GetChildRows 方法。订单明细表中的所有相关记录都将分配给名为
draOrderDetails
的数据行数组。每个数据行的内容将显示在 RTF 文本框中。
注意:请注意嵌套的 For Each 循环是如何首先选取一个数据行,然后在该数据行的所有列中循环以访问整个相关记录的。
设置 RTF 文本框以显示所有订单明细
在 Solution Explorer(解决方案资源管理器)中,右键单击 Form1 并从快捷菜单中选择 View Designer(视图设计器)。
双击列表框为列表框 lbOrders 的 SelectedIndexChanged 事件创建事件处理程序。
添加以下代码:
' Visual Basic
Private Sub lbOrders_SelectedIndexChanged _
(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles lbOrders.SelectedIndexChanged
' 选择新订单时,清除 RTF 文本框。
rtbDetails.Clear()
' 声明一个用来保存选定的订单 ID 的整数。
Dim SelectedOrderID As Integer
' 将选定的项目设置为整数。
SelectedOrderID = CType(lbOrders.SelectedItem, Integer)
' 声明一个用来保存选定订单的记录的数据行。
Dim drSelectedOrder As DataRow
drSelectedOrder = _
DsNorthwind1.Orders.FindByOrderID(SelectedOrderID)
' 声明一个用来保存相关记录的数据行数组。
Dim draOrderDetails() As DataRow
draOrderDetails = _
drSelectedOrder.GetChildRows("OrdersOrderDetails")
Dim details As String = ""
Dim drDetails As DataRow
Dim dcDetails As DataColumn
For Each drDetails In draOrderDetails
For Each dcDetails In drDetails.Table.Columns
details &= dcDetails.ColumnName &": "
details &= drDetails(dcDetails).ToString()
details &= ControlChars.CrLf
Next
details &= ControlChars.CrLf
Next
rtbDetails.Text = details
End Sub
// C#
private void lbOrders_SelectedIndexChanged
(object sender, System.EventArgs e)
{
// 选择新订单时,清除 RTF 文本框。
rtbDetails.Clear()
// 声明一个用来保存选定的订单 ID 的整数。
int SelectedOrderID
// 将选定的项目设置为整数。
SelectedOrderID = (int)lbOrders.SelectedItem
// 声明一个用来保存选定订单的记录的数据行。
DataRow drSelectedOrder
drSelectedOrder =
dsNorthwind1.Orders.FindByOrderID(SelectedOrderID)
// 声明一个用来保存相关记录的数据行数组。
DataRow[] draOrderDetails
draOrderDetails =
drSelectedOrder.GetChildRows("OrdersOrderDetails")
string details = ""
foreach(DataRow drDetails in draOrderDetails)
{
foreach(DataColumn dcDetails in drDetails.Table.Columns)
{
details += dcDetails.ColumnName + ": "
details += drDetails[dcDetails].ToString() + "\n"
}
details += "\n"
}
rtbDetails.Text = details
}
保存项目。
运行应用程序。
在列表框中选择一个订单,其订单明细将显示在 RTF 文本框中。
在列表框中选择另一个订单。RTF 文本框中的订单明细将被更新。
浏览多对多关系
构成多对多关系的表通常通过保证数据完整性的第三方表进行连接。在罗斯文数据库中,订单表和产品表就是这样相关的。因为有些订单可能包含很多产品,而有些产品又在很多订单中销售。这两个表是通过订单明细表连接的,订单明细表利用这两个表中的列建立自己特定的列,并使这些数据相关。浏览构成多对多关系的三个表与处理一对多关系的表并没有太大区别。
http://www.microsoft.com/china/MSDN/library/archives/library/dv_vstechart/html/vbtchnavigatingmultiplerelatedtablesinADOnetdataset.asp
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)