zoukankan      html  css  js  c++  java
  • 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 方法获取的.

  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/lionwang/p/4430112.html
Copyright © 2011-2022 走看看