用于行DataAdapter.Fill方法()行为在数据源中删除(DataAdapter.Fill(

2019-09-17 22:24发布

我使用DataSet / DataTable / DataAdapter体系结构的数据库和我的模型对象,它们有自己的支持(它们不是由一个DataRow支持)之间进行调解。 我有一个DataAdapterAcceptChangesDuringFill = FalseAcceptChangesDuringUpdate = False ,并FillLoadOption = OverwriteChanges 。 这是我的理解DataAdapter这些条件下的模型:

DataAdapter.Update()

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

DataAdapter.Fill方法()

  • 在返回的结果集,其主键对应于现有行的任何行DataTable将用于更新该行,该行的状态会一直变DataRowState.Modified即使返回的行与当前行
  • 在返回的结果集,其主键不对应于任何现有的行会被用来创建一个新的行中的任意行,该行的状态将成为DataRowState.Added
  • 在任何行DataTable不对应的行中返回的结果集将留在DataRowState.Unchanged

鉴于我与这个心智模式是正确的,假设我想用Fill()注意在数据源中删除的行。 此外,假设参数SelectCommand不返回整个表。 我猜,我有两个选择:

  • 查找应该已经被更新的所有行Fill()但仍然DataRowState.Unchanged (以上依靠未经检验我的假设斜体)。 这些行已经在数据源中被删除。
  • 清除从所有相关行DataTable的前Fill() ; 以后不会再出现任何行已经在数据源中被删除。 这失去的区别DataRowState.AddedDataRowState.Modified被保留与第一种方法。

所以,我的问题:

  • 是我上面的模型DataAdapter是正确的,符合我在上面提到的属性值?
  • 我应该去找到删除的行哪个选项? 我更喜欢第一个,但是这依赖于我的假设,即所有返回的行会被设置为DataRowState.Modified即使该行是相同的; 是一个安全的假设?
  • 我要对所有这一切错了吗?

Answer 1:

原来,我的假设是错误的,如果返回的行SelectCommand是完全一样的,在一排已经DataTable ,该行仍标记为DataRowState.Unchanged 。 所以,正确的方法是从消除行DataTable调用之前Fill()并通过一套新的比较来确定一个行的命运DataRowState.Added行的行前清单。



Answer 2:

我看到了类似的问题,但我不能使用.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

更多的优雅的解决方案的任何建议表示赞赏。



文章来源: DataAdapter.Fill() behavior for row deleted at the data source