• DataRow的RowState属性变化


    DataRow的RowState属性(状态)取值有5种:Detached, Unchanged, Added, Deleted, Modified。

    当我们用DataRow newRow = DataTable.NewRow();方法产生一个新的DataRow时,它的状态是Detached. 然后我们会将这个newRow用DataTable.Rows.Add(newRow); 方法添加到DataTable中。此时newRow的状态是Added, 这个时候执行DataTable.AcceptChanges()方法,提交改动。此时newRow的状态是Unchanged, 这个时候呢,当然可以执行newRow.Delete()操作或是DataTable.Remove(newRow)或是编辑这一行啊,但是注意此时执行之后对应的状态分别是Deleted, Detached, Modified. 如果再执行DataTable.AcceptChanges()方法,提交改动状态分别是Detached, Detached, Unchanged. 而 newRow.Delete()与DataTable.Remove(newRow)的区别就是newRow.Delete()并没有直接从DataTable里移除newRow, 而只是将其状态变为Deleted, 因此需要调用DataTable.AcceptChanges()提交更改才能移除,移除的概念是将其状态变为Detached, 并没有真的将newRow消灭,而DataTable.Remove(newRow)方法直接将newRow状态变为Detached, 不用再调用DataTable.AcceptChanges()提交更改。但如果在newRow状态为Added的时候执行newRow.Delete(), 那就直接移除,并将其状态变为Detached. 有提交更改自然也有与之对应的回滚操作DataTable.RejectChanges(), 值得注意的是回滚操作会分别将状态为Added, Deleted, Modified, 统统变为最近一次的Unchanged.对于状态已经为Detached的,DataTable.RejectChanges()方法是无能为力的。

    下面是更详细的讲解:

    1. RowState 介绍

    RowState 是 DataRow 很重要的一个属性, 表示 DataRow 当前的状态. RowState 有 Added, Modified, Unchanged, Deleted, Detached 几种, 分别表示 DataRow 被添加, 修改, 无变化, 删除, 从表中脱离. 在调用一些方法或者进行某些操作之后, 这些状态可以相互转化.

    DataAdapter 可以根据 RowState 来决定如何影响数据库等存储位置. 如果 DataRow 的状态为 Added, DataAdapter将把 DataRow 添加到数据库等存储位置, 对于 Modified, Deleted 则将执行更新和删除操作. 其实, 最终的操作效果还是决定于 DataAdapter 的 SelectCommand, UpdateCommand 等 DbCommand. 如果, 在 UpdateCommand 中写入 Delete 语句或者执行有删除操作的存储过程, 那么状态为 Modified 的 DataRow 最终将在数据库中删除而不是更新. (注: 下文中所说的 DataAdapter 操作均如此.)

    2. 从不同位置载入 DataRow 后 RowState 的状态

    a. 从 xml 文件或者使用 DataTable.Rows.Add(params object[]) 方法添加的 DataRow 的 RowState 为 Added.
    使用上面方式增加的 DataRow, 如果使用 DataAdapter 更新, 将执行 insert 操作, 例如: 添加到 sql server 数据库中.

    b. 如果 DataAdapter.AcceptChangesDuringFill 属性为 true, 使用 DataAdapter.Fill 方法填充的 DataRow 的 RowState 为 Unchanged, 否则, 为 Added, 默认 AcceptChangesDuringFill 为 true.
    例如: 默认情况下, 从 sql server 数据库读取的 DataRow, 然后直接使用 DataAdapter 更新的话, 是不会有任何数据被修改的, 因为 DataAdapter 不对状态为 Unchanged 的 DataRow 执行任何操作.

    3. 修改, 更改, 删除后的 DataRow.RowState 转化

    a. 对于状态为 Unchanged 或者 Modified 的 DataRow, 修改数据后的状态为 Modified.
    这表示 DataRow 需要将自己的数据通过 DataAdapter 更新回数据库等存储位置. 因为, DataRow 中的数据可能已经和自己先前的版本不同.

    b. 对于状态为 Added 的 DataRow, 修改数据后仍然为 Added.
    DataAdapter 对状态为 Added 的 DataRow 将执行添加操作. 很明显, 即使修改 DataRow 仍然应该保持状态为 Added, 否则无法在 DataAdapter 更新的时候被添加到数据库等存储位置.

    c. 如果 DataAdapter.AcceptChangesDuringUpdate 属性为 true, 使用 DataAdapter.Update 更新后的 DataRow 的状态为 Unchanged, 否则, DataRow 的状态保持不变, 默认 AcceptChangesDuringUpdate 为 true.
    默认情况下, 状态为 Unchanged 说明 DataRow 当前的数据没有经历过改变, 你可以认为和数据库中的数据一致, 但并非都如此.

    d. 对于状态为 Unchanged 的 DataRow, 调用 Delete 方法后状态为 Deleted.
    DataAdapter 对状态为 Deleted 的 DataRow 执行删除操作, 将数据库等存储位置的对应数据删除.

    e. 对于状态为 Added 的 DataRow, 调用 Delete 方法后状态为 Detached.
    Added 状态的 DataRow 可能并不存在于数据库等存储位置, 因此状态转化为 Detached 而不是 Deleted,DataAdapter 不会处理状态为 Detached 的 DataRow.

    f. 使用 DataTable.Rows.Remove 方法移除 DataRow 后, DataRow 状态为 Detached.

    4. 使用 AcceptChanges, RejectChanges, SetAdded, SetModified 方法后 DataRow.RowState 的转化

    a. 状态为 Unchanged, Added, Modified 的 DataRow, 使用 DataRow.AcceptChanges 方法, 行状态将转化为 Unchanged.
    以上三种状态的 DataRow, 其目的相当于添加或者修改数据, 因此接受变化后这些 DataRow 存在于 DataTable 中, 并且状态为 Unchanged. 如果这时使用 DataAdapter 更新, 将不会对数据库等存储位置有任何的影响, 因为状态已经为 Unchanged, 这本应该在 DataAdapter 更新后转化的.

    b. 状态为 Deleted 的 DataRow, 使用 DataRow.AcceptChanges 方法, 行状态转化为 Detached.
    目的为删除数据的 DataRow, 接受变化后就从 DataTable 中脱离, 因此状态变为 Detached.

    c. 状态为 Detached 的 DataRow, 不能使用 DataRow.AcceptChanges 方法.

    d. 状态为 Unchanged, Modified, Deleted 的 DataRow, 使用 DataRow.RejectChanges 方法, 行状态将转化为 Unchanged.
    以上三种状态的 DataRow, 其目的相当于删除或者修改数据, 因此拒绝变化后这些 DataRow 存在于 DataTable 中, 并且状态为 Unchanged. 如果这时使用 DataAdapter 更新, 其情况将类似于 a.

    e. 状态为 Added, Detached 的 DataRow, 使用 DataRow.RejectChanges 方法, 行状态将转化为 Detached.
    状态为 Added 的 DataRow 目的在于添加, 因此拒绝后从 DataTable 脱离, 状态为 Detached.

    f. 对状态为 Unchanged 的 DataRow, 可以使用 DataRow.SetAdded, DataRow.SetModified 方法使行状态转化为 Added 或者 Modified.
    SetAdded, SetModified 方法对状态不是 Unchanged 的 DataRow 使用将抛出异常.

    5. 使用 ImportRow, Copy 方法后 DataRow.RowState 的转化

    a. 使用 DataTable.ImportRow 方法导入 DataRow 后, 导入的 DataRow 和原 DataRow 的行状态一致.
    ImportRow 方法采用复制的方式导入 DataRow, 状态为 Detached 的 DataRow, 无法导入到 DataTable, 但不会产生异常.

    b. 使用 DataTable.Copy 或者 DataSet.Copy 方法, DataRow 的状态保持不变.

    6. 访问不同 RowState 的 DataRow 中的数据

    a. 对于状态为 Added, Unchanged, Modified 的 DataRow, 可以方便的通过 DataRow[<列名>] 访问数据.

    b. 状态为 Deleted 的 DataRow 需要使用 DataRow[<列名>, DataRowVersion.Original] 来访问.
    对于已经调用 Delete 方法的 DataRow, 需要指定访问数据的 Original 版本.

    c. 状态为 Detched 的 DataRow, 似乎没有方法访问其中的数据.
    DataRow 已经从 DataTable 中移除, 这可能使其中的数据无法访问.

    7. 获取 DataTable 中不同 RowState 的 DataRow

    a. 可以通过 DataTable.GetChanges(DataRowState) 得到 DataTable 中不同 RowState 的 DataRow 的副本.
    GetChanges 方法将返回一个新的 DataTable, 其中包含了指定行状态的 DataRow 的副本, 修改这些副本不会影响原DataTable 中的 DataRow. 如果使用不带参数的 GetChanges 方法将返回包含行状态为 Added, Modified, Deleted 的DataRow 副本的 DataTable. 可以使用位或运算符 | 组合获取多种状态的 DataRow. 另外, 状态为 Detached 的DataRow 似乎是无法通过 GetChanges 方法获取的.

  • 相关阅读:
    Android关闭所有Activity、退出应用
    Android混淆打包找不到资源类的…
    Android查看网络是否可用
    Android获取当前系统的语言环境
    AndroidActivity之间跳转动画
    Android获得0n随机排列的数组
    Android记录和恢复listView滚动位置
    Android获取电池信息(Battery&nbsp;in…
    AndroidSurfaceView截屏问题
    Android让Activity finish后不执行onDestroy
  • 原文地址:https://www.cnblogs.com/lionwang/p/4430112.html
Copyright © 2020-2023  润新知