演练:在事务中保存数据
此演练演示如何使用 System.Transactions 命名空间在事务中保存数据。 此示例使用源自 Northwind 示例数据库的 Customers 和 Orders 表。
系统必备
此演练需要访问 Northwind 示例数据库。 有关设置 Northwind 示例数据库的信息,请参见 如何:安装示例数据库。
创建 Windows 应用程序
第一步是创建**“Windows 应用程序”**。
创建新的 Windows 项目
在 Visual Studio 中,从**“文件”菜单创建一个新的“项目”**。
将项目命名为 SavingDataInATransactionWalkthrough。
选择**“Windows 应用程序”,然后单击“确定”**。 有关更多信息,请参见 开发客户端应用程序。
创建**“SavingDataInATransactionWalkthrough”项目并将其添加到“解决方案资源管理器”**中。
创建数据库数据源
此步骤使用 数据源配置向导 在 Northwind 示例数据库中创建基于 Customers 和 Orders 表的数据源。
创建数据源
在**“数据”菜单上,单击“显示数据源”**。
在**“数据源”窗口中,选择“添加新数据源”,启动“数据源配置向导”**。
在**“选择数据源类型”页上选择“数据库”,然后单击“下一步”**。
在**“选择您的数据连接”**页面上执行下列操作之一:
如果下拉列表中包含到 Northwind 示例数据库的数据连接,请选择该连接。
- 或 -
选择**“新建连接”,启动“添加/修改连接”**对话框,并创建到 Northwind 数据库的连接。 有关更多信息,请参见“添加/修改连接”对话框(通用)。
如果数据库需要密码,请选择该选项以包括敏感数据,再单击**“下一步”**。
在**“将连接字符串保存到应用程序配置文件”页面上单击“下一步”**。
在**“选择数据库对象”页面上展开“表”**节点。
选择 Customers 和 Orders 表,再单击**“完成”**。
**“NorthwindDataSet”被添加到您的项目中,并且“数据源”**窗口中出现 Customers 和 Orders 表。
向窗体添加控件
可以通过将某些项从**“数据源”**窗口拖到您的窗体上来创建数据绑定控件。
在 Windows 窗体上创建数据绑定控件
在**“数据源”窗口中展开“Customers”**节点。
将主**“Customers”节点从“数据源”窗口拖到“Form1”**上。
用于导航记录的 DataGridView 控件和工具栏(BindingNavigator)出现在窗体上。 组件栏中出现 NorthwindDataSet、CustomersTableAdapter、BindingSource 和 BindingNavigator。
将相关的**“Orders”节点(“Fax”列下面的相关子表节点,而非主“Orders”节点)拖到“CustomersDataGridView”**下面的窗体上。
窗体上显示一个 DataGridView。 OrdersTableAdapter 和 BindingSource 出现在组件栏中。
添加对 System.Transactions 程序集的引用
事务使用 System.Transactions 命名空间。 默认情况下,没有添加对 system.transactions 程序集的项目引用,因此您需要手动将其添加。
添加对 System.Transactions DLL 文件的引用
从**“项目”菜单中选择“添加引用”**。
选择**“System.Transactions”(在“.NET”选项卡上),并单击“确定”**。
对**“System.Transactions”**的引用被添加到项目。
修改 BindingNavigator 的 SaveItem 按钮中的代码
默认情况下,由于第一个表已放在您的窗体上,因此代码被添加到 BindingNavigator 上保存按钮的 click 事件中。 您需要手动添加代码以更新所有附加的表。 对于此演练,我们将重构源自保存按钮的 click 事件处理程序的现有保存代码,并创建更多的方法以根据是需要添加行还是需要删除行提供特定的更新功能。
修改自动生成的保存代码
双击**“CustomersBindingNavigator”上的“保存”**按钮(带有软盘图标的按钮)。
用下面的代码替换 CustomersBindingNavigatorSaveItem_Click 方法:
Private Sub CustomersBindingNavigatorSaveItem_Click() Handles CustomersBindingNavigatorSaveItem.Click UpdateData() End Sub Private Sub UpdateData() Me.Validate() Me.CustomersBindingSource.EndEdit() Me.OrdersBindingSource.EndEdit() Using updateTransaction As New Transactions.TransactionScope DeleteOrders() DeleteCustomers() AddNewCustomers() AddNewOrders() updateTransaction.Complete() NorthwindDataSet.AcceptChanges() End Using End Sub
private void customersBindingNavigatorSaveItem_Click(object sender, EventArgs e) { UpdateData(); } private void UpdateData() { this.Validate(); this.customersBindingSource.EndEdit(); this.ordersBindingSource.EndEdit(); using (System.Transactions.TransactionScope updateTransaction = new System.Transactions.TransactionScope()) { DeleteOrders(); DeleteCustomers(); AddNewCustomers(); AddNewOrders(); updateTransaction.Complete(); northwindDataSet.AcceptChanges(); } }
对相关数据的协调更改的顺序如下:
删除子记录(在此情况下,从 Orders 表中删除记录)
删除父记录(在此情况下,从 Customers 表中删除记录)
插入父记录(在此情况下,在 Customers 表中插入记录)
插入子记录(在此情况下,在 Orders 表中插入记录)
删除现有顺序
将下面的 DeleteOrders 方法添加到**“Form1”**:
Private Sub DeleteOrders() Dim deletedOrders As NorthwindDataSet.OrdersDataTable deletedOrders = CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Deleted), NorthwindDataSet.OrdersDataTable) If Not IsNothing(deletedOrders) Then Try OrdersTableAdapter.Update(deletedOrders) Catch ex As Exception MessageBox.Show("DeleteOrders Failed") End Try End If End Sub
private void DeleteOrders() { NorthwindDataSet.OrdersDataTable deletedOrders; deletedOrders = (NorthwindDataSet.OrdersDataTable) northwindDataSet.Orders.GetChanges(DataRowState.Deleted); if (deletedOrders != null) { try { ordersTableAdapter.Update(deletedOrders); } catch (System.Exception ex) { MessageBox.Show("DeleteOrders Failed"); } } }
删除现有客户
将下面的 DeleteCustomers 方法添加到**“Form1”**:
Private Sub DeleteCustomers() Dim deletedCustomers As NorthwindDataSet.CustomersDataTable deletedCustomers = CType(NorthwindDataSet.Customers.GetChanges(Data.DataRowState.Deleted), NorthwindDataSet.CustomersDataTable) If Not IsNothing(deletedCustomers) Then Try CustomersTableAdapter.Update(deletedCustomers) Catch ex As Exception MessageBox.Show("DeleteCustomers Failed" & vbCrLf & ex.Message) End Try End If End Sub
private void DeleteCustomers() { NorthwindDataSet.CustomersDataTable deletedCustomers; deletedCustomers = (NorthwindDataSet.CustomersDataTable) northwindDataSet.Customers.GetChanges(DataRowState.Deleted); if (deletedCustomers != null) { try { customersTableAdapter.Update(deletedCustomers); } catch (System.Exception ex) { MessageBox.Show("DeleteCustomers Failed"); } } }
添加新客户
将下面的 AddNewCustomers 方法添加到**“Form1”**:
Private Sub AddNewCustomers() Dim newCustomers As NorthwindDataSet.CustomersDataTable newCustomers = CType(NorthwindDataSet.Customers.GetChanges(Data.DataRowState.Added), NorthwindDataSet.CustomersDataTable) If Not IsNothing(newCustomers) Then Try CustomersTableAdapter.Update(newCustomers) Catch ex As Exception MessageBox.Show("AddNewCustomers Failed" & vbCrLf & ex.Message) End Try End If End Sub
private void AddNewCustomers() { NorthwindDataSet.CustomersDataTable newCustomers; newCustomers = (NorthwindDataSet.CustomersDataTable) northwindDataSet.Customers.GetChanges(DataRowState.Added); if (newCustomers != null) { try { customersTableAdapter.Update(newCustomers); } catch (System.Exception ex) { MessageBox.Show("AddNewCustomers Failed"); } } }
添加新顺序
将下面的 AddNewOrders 方法添加到**“Form1”**:
Private Sub AddNewOrders() Dim newOrders As NorthwindDataSet.OrdersDataTable newOrders = CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Added), NorthwindDataSet.OrdersDataTable) If Not IsNothing(newOrders) Then Try OrdersTableAdapter.Update(newOrders) Catch ex As Exception MessageBox.Show("AddNewOrders Failed" & vbCrLf & ex.Message) End Try End If End Sub
private void AddNewOrders() { NorthwindDataSet.OrdersDataTable newOrders; newOrders = (NorthwindDataSet.OrdersDataTable) northwindDataSet.Orders.GetChanges(DataRowState.Added); if (newOrders != null) { try { ordersTableAdapter.Update(newOrders); } catch (System.Exception ex) { MessageBox.Show("AddNewOrders Failed"); } } }
运行应用程序
运行应用程序
- 按 F5 运行该应用程序。
请参见
任务
概念
Enlisting in Distributed Transactions
Leveraging System.Transactions