演练:保存相关数据表中的数据(分层更新)
在使用单个数据表且不需要考虑任何外键约束的情况下,将应用程序中的数据存回到数据库中非常简单。 但当您需要保存包含两个或更多相关数据表的数据集中的数据时,为了避免违反约束,必须将对数据表的更改以特定顺序发送到数据库。 在相关表中更新修改过的数据时,可以提供编程逻辑来从每个数据表中提取特定的数据子集,并以正确的顺序将更新发送到数据库,也可以使用 TableAdapterManager 组件。
本演练演示如何使用 TableAdapterManager 组件保存相关数据。 有关手动编写相关数据表更新的代码的信息,请参见演练:将数据保存到数据库(多个表)。
系统必备
若要完成本演练,您需要:
- 能够访问 Northwind 示例数据库。 有关更多信息,请参见如何:安装示例数据库。
创建基于 Windows 的应用程序
本演练的第一步是创建新的基于 Windows 的应用程序。
创建新的基于 Windows 的应用程序
从**“文件”**菜单创建一个新的项目。
提示
由于 Visual Basic 项目和 C# 项目都支持分层更新,所以可以使用这两种语言中的任意一种来创建新项目。
将项目命名为 HierarchicalUpdateWalkthrough。
选择**“Windows 窗体应用程序”,然后单击“确定”**。 有关更多信息,请参见创建基于 Windows 的应用程序。
**“HierarchicalUpdateWalkthrough”项目即被创建并添加到“解决方案资源管理器”**中。
创建数据集
由于您需要相关表来演示分层更新,因此下一步要从 Northwind 数据库创建包含 Customers 和 Orders 表的数据集。 使用**“数据源配置向导”**来创建数据集。 必须具有访问 Northwind 示例数据库的权限才能创建连接。 有关如何设置 Northwind 示例数据库的信息,请参见如何:安装示例数据库。
创建数据集
在**“数据”菜单上,单击“显示数据源”**。
在**“数据源”窗口中,单击“添加新数据源”,启动“数据源配置向导”**。
在**“选择数据源类型”页上,单击“数据库”,然后单击“下一步”**。
在**“选择您的数据连接”**页上执行下列操作之一:
如果下拉列表框中包含与 Northwind 示例数据库的数据连接,请单击该连接。
- 或 -
单击**“新建连接”,打开“添加/修改连接”**对话框。 有关更多信息,请参见“添加/修改连接”对话框(通用)。
如果数据库需要密码,请选择该选项以包括敏感数据,再单击**“下一步”**。
在**“将连接字符串保存到应用程序配置文件中”页上单击“下一步”**。
在**“选择数据库对象”页面上展开“表”**节点。
单击**“Customers”和“Orders”表的复选框,然后单击“完成”**。
**“NorthwindDataSet”将被创建并添加到您的项目中,并在“数据源”**窗口中显示这些表。
更改要创建的默认数据绑定控件
填充**“数据源”窗口后,可以选择将项拖到 Windows 窗体时要创建的控件。 对于本演练,Customers 表中的数据将在单独的控件(“Details”)中显示。 Orders 表中的数据将在 DataGridView 控件(“DataGridView”**)中显示。
为“数据源”窗口中的项设置控件
在**“数据源”窗口中展开“Customers”**节点。
在**“Customers”节点的控件列表中单击“Details”,将要为“Customers”**表创建的控件更改为单独的控件。 有关更多信息,请参见如何:设置从“数据源”窗口中拖动时要创建的控件。
提示
“Orders”表将使用默认控件“DataGridView”。
创建数据绑定窗体
在**“数据源”**窗口中选择控件后,可以通过将某些项拖到窗体上来创建数据绑定控件。
为 Customers 和 Orders 数据创建数据绑定控件
将主**“Customers”节点从“数据源”窗口拖到“Form1”**上。
带有描述性标签的数据绑定控件会出现在窗体上,同时还显示一个**“TableAdapterManager”**组件和一个用于在记录间进行导航的工具栏 (BindingNavigator)。 组件栏中将出现一个类型化的 DataSet、TableAdapter 和一个 BindingSource。
将相关的**“Orders”节点从“数据源”窗口拖动到“Form1”**上。
提示
相关的“Orders”节点是“Customers”节点的子节点,位于 customers 表的“Fax”节点下。 与“Customers”节点同级的“Orders”节点表示表中的所有订单。 作为“Customers”节点的子节点的“Orders”节点表示相关订单。
一个 DataGridView 控件和一个用于在记录间进行导航的工具栏 (BindingNavigator) 出现在窗体上。 TableAdapter 和 BindingSource 出现在组件栏中。
修改生成的保存代码以执行分层更新
通过调用 TableAdapterManager.UpdateAll 方法并传入包含相关表的数据集的名称,可将数据集中相关数据表的更改保存到数据库。 例如,运行 TableAdapterManager.UpdateAll(NorthwindDataset) 方法将 NorthwindDataset 中所有表的更新发送到后端数据库。
从**“数据源”窗口拖放项后,代码会自动添加到 Form_Load 事件以填充每个表(TableAdapter.Fill 方法)。 系统还会向 BindingNavigator 的“保存”**按钮单击事件添加代码,将数据集中的数据存回数据库中(TableAdapterManager.UpdateAll 方法)。
生成的保存代码还包含调用 CustomersBindingSource.EndEdit 方法的一行代码。 更具体地说,它调用添加到窗体的第一个 BindingSource 的 EndEdit 方法。 也就是说,此代码只是为从**“数据源”窗口拖到窗体上的第一个表生成的。 EndEdit 调用将提交当前正在编辑的任何数据绑定控件中的所有更改。 因此,如果焦点仍在数据绑定控件上并且您单击了“保存”**按钮,则会先提交该控件中所有挂起的编辑,再执行真正的保存(TableAdapterManager.UpdateAll 方法)。
提示
设计器只为拖放到窗体上的第一个表添加 BindingSource.EndEdit 代码。 因此,必须对窗体上的每个相关表添加一行调用 BindingSource.EndEdit 方法的代码。 对于本演练,这意味着您必须添加一个对 OrdersBindingSource.EndEdit 方法的调用。
更新代码以在保存前提交对相关表的更改
双击 BindingNavigator 上的**“保存”按钮以在代码编辑器中打开“Form1”**。
在调用 CustomersBindingSource.EndEdit 方法的代码行后添加一行调用 OrdersBindingSource.EndEdit 方法的代码。 **“保存”**按钮单击事件中的代码应如下所示:
Me.Validate() Me.CustomersBindingSource.EndEdit() Me.OrdersBindingSource.EndEdit() Me.TableAdapterManager.UpdateAll(Me.NorthwindDataSet)
this.Validate(); this.customersBindingSource.EndEdit(); this.ordersBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwindDataSet);
除了在将数据保存到数据库之前提交对相关子表的更改外,您可能还需要在向数据集添加新子记录之前先提交新创建的父记录。 也就是说,您可能需要先向数据集添加新父记录 (Customer),然后外键约束才允许将新子记录 (Orders) 添加到数据集中。 为实现这一点,可以使用子 BindingSource.AddingNew 事件。
提示
提交新父记录不是必需的;具体取决于用于绑定到数据源的控件的类型。 在本演练中,您使用单独的控件绑定到父表;这需要额外的代码来提交新的父记录。 如果父记录在类似于 DataGridView 的复杂绑定控件中显示,则对该父记录的额外 EndEdit 调用不是必需的。 这是因为这类控件的基础数据绑定功能可以提交新记录。
添加代码以在添加新子记录之前在数据集中提交父记录
为 OrdersBindingSource.AddingNew 事件创建一个事件处理程序。
- 在设计视图中打开**“Form1”,在组件栏中单击“OrdersBindingSource”,在“属性”窗口中选择“事件”,然后双击“AddingNew”**事件。
向事件处理程序添加调用 CustomersBindingSource.EndEdit 方法的一行代码。 OrdersBindingSource_AddingNew 事件处理程序中的代码应如下所示:
Me.CustomersBindingSource.EndEdit()
this.customersBindingSource.EndEdit();
验证分层更新已启用
通过设置数据集的**“分层更新”属性可打开或关闭分层更新。 默认情况下启用分层更新,因此对于本演练,不需要更改“分层更新”**属性的值。
验证分层更新已启用
在**“解决方案资源管理器”中双击“NorthwindDataSet.xsd”文件,以在“数据集设计器”**中打开该数据集。
选择设计图面上的空白区域。
在“属性”窗口中找到**“分层更新”属性,然后检查它是否设置为“True”**。
提示
“分层更新”属性设置用于控制生成的代码是否带有 TableAdapterManager 和执行分层更新所需的逻辑。 将“HierarchicalUpdate”设置为“True”将生成 TableAdapterManager;将“HierarchicalUpdate”设置为“False”则不生成 TableAdapterManager。
测试应用程序
测试应用程序
按 F5。
对每个表中的一条或多条记录的数据执行一些更改。
添加新客户,然后添加该客户的新订单。
单击**“保存”**按钮。 TableAdapterManager 将处理所有相关更新所需的逻辑。
检查数据库中的值以验证更改已保存到每个表中。
后续步骤
根据应用程序的要求,在基于 Windows 的应用程序中保存相关数据后,可能还要执行一些步骤。 您可以对此应用程序进行的增强包括:
添加第三个表,例如 OrderDetails 表,体验一下三个表的层次结构。
添加验证代码以验证数据满足应用程序的要求和数据库约束。 有关更多信息,请参见验证数据。
请参见
任务
如何:在现有 Visual Studio 项目中实现分层更新