在 ADO.NET 数据集中维护 DataRowState - RejectChanges() 方法不起作用?

发布于 2024-07-30 11:02:16 字数 776 浏览 10 评论 0原文

问题简化了:

我有一个带有一些数据表的数据集...... 我有一个绑定到其中一个数据表的 Winforms DataGrid。 用户通过 DataGrid 将一些行粘贴到所述数据表中,假设 3 行;

现在,所有三行的 RowState = DataRowState.Added。

我现在开始一个 sqlserver 事务。

然后调用 dataAdapter1.Update(dataSet1) 将行更新到 SqlServer 中。 第 1 行.. 好的 第 2 行.. 好的 第 3 行.. sqlserver 级别的错误(根据设计,我强制执行了唯一索引)

检测到此错误后,我回滚 sqlserver 事务。

我还尝试使用 Dataset1.RejectChanges() 和/或 Datatable1.RejectChanges() 来“回滚”数据表/数据集更改。

问题是 .RejectChanges() 都没有按照我设想的方式工作。 我的数据表现在有两行(row1,row2),其 RowState = DataRowState.Unchanged; row3 完全消失了。

我想要发生的是,当我回滚 sqlserver 事务时,数据表中的所有 3 行在调用 dataAdapter1.Update() 方法之前保持相同状态。

(原因是用户可以查看绑定的 DataGrid 中的错误,采取纠正措施,然后再次尝试更新)。

有人有什么想法吗? 即我正在寻找相当于在 ADO 数据表级别回滚状态的东西。

The problem simplified:

I have a DataSet with some datatables...
I have a Winforms DataGrid bound to one of the datatables.
User sticks some rows into said datatable, via the DataGrid, let's say 3 rows;

All three rows now have their RowState = DataRowState.Added.

I now begin a sqlserver transaction.

Then call dataAdapter1.Update(dataSet1) to update rows into SqlServer.
row 1.. OK
row 2.. OK
row 3.. error at the sqlserver level (by design i enforced a unique index)

Upon detecting this error, i Rollback the sqlserver transaction.

I also try to "rollback" the datatable / dataset changes, using either of Dataset1.RejectChanges() and / or Datatable1.RejectChanges().

Problem is neither of .RejectChanges() work the way i envisaged. My datatable now has two rows (row1, row2), whose RowState = DataRowState.Unchanged; row3 has disappeared altogether.

What i want to happen is, when i roll back the sqlserver transaction, for all 3 rows in the datatable to remain in the SAME STATE just prior to the call to dataAdapter1.Update() method.

(Reason is so that the user can look at the error in the bound DataGrid, take corrective action, and attempt the Update again).

Any ideas anyone? i.e. i am looking for something equivalent to rolling back the state at the ADO dataTable level.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

入画浅相思 2024-08-06 11:02:16

好吧,所以我想出了一个方法来解决这个问题。

获取原始数据表的克隆,并更新克隆。

如果发生错误,您仍然拥有原始数据表及其原始 DataRowState; 此外,您可以将克隆中发生的任何错误复制到原始数据表中,从而将错误反映在数据网格中供用户查看。

如果更新成功,您只需使用克隆刷新原始数据表即可。

VB代码:

Try
    'daMyAdapter.Update(dsDataset, "MyDatatable") <-- replace original with below lines.
    _dtMyDatatableClone = dsDataset.MyDatatable.Copy()

    If _dtMyDatatableClone IsNot Nothing Then
      daMyAdapter.Update(_dtMyDatatableClone)

       'if you get here, update was successul - refresh now!
       dsDataset.MyDatatable.Clear()
       dsDataset.MyDatatable.Merge(_dtMyDatatableClone, False, MissingSchemaAction.Ignore)
    End If
Catch
    'uh oh, put error handler here.
End Try

Ok, so i figured a way to get around this.

Get a clone of the original datatable, and update the clone.

If an error occurs, you still have the original datatable, with its original DataRowState; Furthermore, you can copy any errors that occur in the clone to the original Datatable, thus reflecting the errors in the datagrid for the user to see.

If update is successful, you simply refresh the original datatable with the clone.

VB Code:

Try
    'daMyAdapter.Update(dsDataset, "MyDatatable") <-- replace original with below lines.
    _dtMyDatatableClone = dsDataset.MyDatatable.Copy()

    If _dtMyDatatableClone IsNot Nothing Then
      daMyAdapter.Update(_dtMyDatatableClone)

       'if you get here, update was successul - refresh now!
       dsDataset.MyDatatable.Clear()
       dsDataset.MyDatatable.Merge(_dtMyDatatableClone, False, MissingSchemaAction.Ignore)
    End If
Catch
    'uh oh, put error handler here.
End Try
因为看清所以看轻 2024-08-06 11:02:16

我在尝试回滚对绑定到 Xceed DataGrid 的 DataTable 的更改时遇到了类似的问题。 在 DataGrid 中进行编辑后,编辑的值都将成为 DataRow 的当前状态的一部分。 RejectChanges 仅适用于防止建议行状态变为当前状态。

为了恢复给定行的更改,我编写了一种方法来用原始版本覆盖当前行版本。 为了将版本设置为原始,您只需在数据表上调用 AcceptChanges() 即可。

    public static void RevertToOriginalValues(DataRow row)
    {
        if (row.HasVersion(DataRowVersion.Original) && row.HasVersion(DataRowVersion.Current))
        {
            for (int colIndex = 0; colIndex < row.ItemArray.Length; colIndex++)
            {
                var original = row[colIndex, DataRowVersion.Original];
                row[colIndex] = original;
            }
        }
    }

I had a similar issue with trying to rollback changes to a DataTable that was bound to an Xceed DataGrid. Once the edits were made in the DataGrid, the edited values all become part of the DataRow's Current state. RejectChanges is only applicable for preventing the Proposed row state from becoming Current.

In order to revert the changes for a given row, I wrote a method to overwrite the current row version with the original version. In order to set a version as the Original, you simply call AcceptChanges() on the datatable.

    public static void RevertToOriginalValues(DataRow row)
    {
        if (row.HasVersion(DataRowVersion.Original) && row.HasVersion(DataRowVersion.Current))
        {
            for (int colIndex = 0; colIndex < row.ItemArray.Length; colIndex++)
            {
                var original = row[colIndex, DataRowVersion.Original];
                row[colIndex] = original;
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文