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

时间:2009-07-07 20:29:37

标签: .net ado.net datatable dataadapter rowstate

我正在使用DataSet / DataTable / DataAdapter架构在数据库和我的模型对象之间进行调解,这些对象有自己的支持(它们不受DataRow支持) )。我有一个DataAdapter AcceptChangesDuringFill = FalseAcceptChangesDuringUpdate = FalseFillLoadOption = 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;这是一个安全的假设吗?
  • 我是不是错了?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

组成
  1. 将DataTable中的字段更改为我知道此字段永远不会有
  2. 的值
  3. 正在运行.Fill
  4. 删除包含此值的所有行
  5. 换句话说:

        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
    

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