4

我正在使用DataSet//体系结构在数据库DataTableDataAdapter我的模型对象之间进行调解,这些对象有自己的支持(它们不受 DataRow 支持)。我有一个DataAdapterwith AcceptChangesDuringFill = False, AcceptChangesDuringUpdate = False, and FillLoadOption = OverwriteChanges。以下是我DataAdapter在这些条件下对模型的理解:

DataAdapter.Update()

  • DataRowState.Added会导致InsertCommand开火
  • DataRowState.Modified会导致UpdateCommand开火
  • DataRowState.Deleted会导致DeleteCommand开火

数据适配器.Fill()

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

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

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

所以,我的问题:

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

2 回答 2

1

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

于 2009-07-08T01:20:40.347 回答
1

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

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

于 2009-08-14T20:08:39.913 回答