在数据源中删除的行的 DataAdapter.Fill() 行为

发布于 2024-07-26 04:00:31 字数 1619 浏览 12 评论 0原文

我使用 DataSet/DataTable/DataAdapter 架构在数据库和我的模型对象之间进行协调,它们有自己的支持(它们是不受 DataRow 支持)。 我有一个带有 AcceptChangesDuringFill = FalseAcceptChangesDuringUpdate = FalseFillLoadOption = OverwriteChangesDataAdapter。 以下是我在这些条件下对 DataAdapter 模型的理解:

DataAdapter.Update()

  • DataRowState.Added 将导致 InsertCommand 触发
  • DataRowState .Modified 将导致 UpdateCommand 触发
  • DataRowState.Deleted 将导致 DeleteCommand 触发

DataAdapter.Fill()

  • 中的任何行返回的结果集(其主键对应于 DataTable 中的现有行)将用于更新该行,并且该行的状态将始终变为 DataRowState.Modified即使返回的行与当前行相同
  • 返回的结果集中主键不对应于任何现有行的任何行都将用于创建新行,并且该行的状态将变为 < code>DataRowState.Added
  • DataTable 中与返回结果集中的行不对应的任何行都将保留在 DataRowState.Unchanged

鉴于我这种心理模型是正确的,假设我想使用 Fill() 来注意到数据源中已删除的行。 另外,假设 SelectCommand 的参数不返回整个表。 我猜我有两个选择:

  • 查找所有应该由 Fill() 更新但仍然是 DataRowState.Unchanged 的行(依赖于我未经测试的上面斜体的假设)。 这些行已在数据源中删除。
  • Fill() 之前清除DataTable 中的所有相关行; 任何不再显示的行都已在数据源中删除。 这会失去使用第一种方法保留的 DataRowState.AddedDataRowState.Modified 之间的区别。

所以,我的问题是:

  • 我的上述 DataAdapter 模型是否正确,是否符合我在顶部注明的属性值?
  • 我应该使用哪个选项来查找已删除的行? 我更喜欢第一个,但这依赖于我的假设,即所有返回的行都将设置为 DataRowState.Modified,即使行相同; 这是一个安全的假设吗?
  • 我这一切都错了吗?

I'm using the DataSet/DataTable/DataAdapter architecture to mediate between the database and my model objects, which have their own backing (they aren't backed by a DataRow). I've got a DataAdapter with AcceptChangesDuringFill = False, AcceptChangesDuringUpdate = False, and FillLoadOption = OverwriteChanges. Here's my understanding of the DataAdapter model under these conditions:

DataAdapter.Update()

  • DataRowState.Added will result in the InsertCommand firing
  • DataRowState.Modified will result in the UpdateCommand firing
  • DataRowState.Deleted will result in the DeleteCommand firing

DataAdapter.Fill()

  • Any row in the returned result set whose primary key corresponds to an existing row in the DataTable will be used to update that row, and that row's state will always become DataRowState.Modified, even if the returned row is identical to the current row
  • Any row in the returned result set whose primary key doesn't correspond to any existing row will be used to create a new row, and that row's state will become DataRowState.Added
  • Any row in the DataTable that doesn't correspond to a row in the returned result set will stay at DataRowState.Unchanged

Given that I'm correct with this mental model, suppose I want to use Fill() to notice deleted rows in the data source. Also, suppose that the parameters of the SelectCommand don't return the entire table. I'm guessing that I have two options:

  • Find all the rows that should've been updated by the Fill() but are still DataRowState.Unchanged (relies on my untested italicized assumption above). These rows have been deleted at the data source.
  • Clear all relevant rows from the DataTable before the Fill(); any row that doesn't show up again has been deleted at the data source. This loses the distinction between DataRowState.Added and DataRowState.Modified that is preserved with the first method.

So, my questions:

  • Is my above model of the DataAdapter correct, subject to the property values I noted at the top?
  • Which option should I go with to find deleted rows? I'd prefer the first one, but that relies on my assumption that all returned rows will be set to DataRowState.Modified even if the row is identical; is that a safe assumption?
  • Am I going about this all wrong?

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

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

发布评论

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

评论(2

℉服软 2024-08-02 04:00:31

事实证明,我的假设是错误的 - 如果 SelectCommand 返回的行与 DataTable 中已有的行完全相同,则该行仍标记为 DataRowState .不变。 因此,正确的过程是在调用 Fill() 之前从 DataTable 中删除行,并通过比较新的 DataRowState.Added< 集来确定行的命运/code> rows 到前一个行列表。

Turns out that my assumption is erroneous—if a row returned by the SelectCommand is exactly the same as a row already in the DataTable, that row remains marked as DataRowState.Unchanged. So the proper procedure is removing rows from the DataTable before calling Fill(), and determining the fate of a row by comparing the new set of DataRowState.Added rows to the former list of rows.

赤濁 2024-08-02 04:00:31

我看到了类似的问题,但我无法使用 .Clear,因为 DataTable 绑定到用户界面列表,并且 .Clear 后跟 .Fill 导致列表丢失用户当前的选择。 因此,我实现了一个(丑陋的)解决方法,它基本上包括

  1. 将 DataTable 中的一个字段更改为一个值,我知道该字段永远不会
  2. 运行 .Fill
  3. 删除包含该值的所有行

换句话说:

    For Each drow As DataRow In dset.Tables(0).Rows
        drow.Item("myField") = -1
    Next

    myDataAdapter.Fill(dset)

    Dim drowsRemove = (From drow In dset.Tables(0).AsEnumerable() _
                       Where drow.Field(Of Integer)("myField") = -1).ToList()
    For Each drow In drowsRemove
        dset.Tables(0).Rows.Remove(drow)
    Next

任何有关更优雅解决方案的建议都将受到赞赏。

I see a similar problem but I cannot use .Clear since the DataTable is bound to a user interface list and .Clear followed by .Fill causes the list to lose the user's current selection. Thus, I implemented a (ugly) workaround which basically consists of

  1. changing a field in the DataTable to a value that I know this field will never have
  2. running .Fill
  3. removing all rows containing this value

In other words:

    For Each drow As DataRow In dset.Tables(0).Rows
        drow.Item("myField") = -1
    Next

    myDataAdapter.Fill(dset)

    Dim drowsRemove = (From drow In dset.Tables(0).AsEnumerable() _
                       Where drow.Field(Of Integer)("myField") = -1).ToList()
    For Each drow In drowsRemove
        dset.Tables(0).Rows.Remove(drow)
    Next

Any suggestions for more elegant solutions are appreciated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文