C#中获取DataTable变更记录的完整方法
在C#开发中,处理内存表数据并追踪变更是实现数据持久化或版本控制的核心环节。本文详解如何利用DataRowState枚举识别记录的增删改状态,结合DataRowVersion区分新旧值,并通过GetChanges方法精准提取变更数据。
理解DataRowState:记录的生命周期状态
DataTable中的每一行(DataRow)都拥有一个 RowState 属性,它是一个枚举类型,用于指示该行在当前内存表中的状态。理解这五种状态是判断数据变更的基础:
- Detached(未附加):新创建但尚未添加到表中,或已从表中移除的行。
- Added(已添加):刚刚被添加到表中的新行。
- Deleted(已删除):标记为删除但仍存在于表中的行。此时物理数据尚未同步删除,且通常无法直接访问该行的当前字段值。
- Modified(已修改):其中的一个或多个列的值已被更改的行。
- Unchanged(无更改):自上次调用
AcceptChanges()后未被修改的行。
区分数据版本:原始值与新值
当需要构建UPDATE语句时,必须知道列的“旧值”和“新值”。通过 DataRowVersion 可以精确指定获取哪个时间点的值:
- Current:获取当前单元格的数值(对于Deleted状态的行无效)。
- Original:获取该行最后一次接受更改时的数值(对于Added状态的行无效,因为初始值即为原始值)。
- Proposed:仅在编辑过程中有效,表示建议的新值。
- Default:根据当前状态自动返回最相关的值。通常在大多数情况下使用此版本进行安全取值。
核心实现:遍历与提取变更数据
DataTable.GetChanges() 方法是获取所有非 Unchanged 状态数据的快捷方式。它返回一个新的DataTable,仅包含变更过的行。结合以下代码,可以完整处理增、删、改的逻辑:
// 1. 初始化示例DataTable
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
// 添加基础数据 (Id: 1-10)
for (int i = 1; i <= 10; i++)
{
dt.Rows.Add(i);
}
dt.AcceptChanges(); // 将当前状态标记为Unchanged
// --- 执行模拟变更 ---
// 情况A:添加新行
var newRow = dt.NewRow();
newRow["Id"] = 11;
dt.Rows.Add(newRow);
// 情况B:修改现有行
// 将第二行 (索引1) 的值改为 21
dt.Rows[1]["Id"] = 21;
// 情况C:删除行
// 删除第一行 (索引0),此时状态变为Deleted
dt.Rows[0].Delete();
// --- 获取并遍历变更数据 ---
// GetChanges() 返回只包含非 Unchanged 行的 DataTable
DataTable changes = dt.GetChanges();
if (changes != null)
{
foreach (DataRow row in changes.Rows)
{
switch (row.RowState)
{
case DataRowState.Added:
// 新增行:只有 Current 值可用
Console.WriteLine($"[新增] 索引 {row.ItemArray[0]} ");
break;
case DataRowState.Deleted:
// 删除行:需获取 Original 值以匹配数据库 WHERE 条件
int originalId = Convert.ToInt32(row["Id", DataRowVersion.Original]);
Console.WriteLine($"[删除] 原ID: {originalId}");
break;
case DataRowState.Modified:
// 修改行:需同时获取 Old 和 New 值用于 UPDATE 语句
string oldVal = row["Id", DataRowVersion.Original].ToString();
string newVal = row["Id", DataRowVersion.Current].ToString();
Console.WriteLine($"[修改] 旧ID: {oldVal} -> 新ID: {newVal}");
break;
}
}
}
结果确认与管理
在完成对变更数据的提取和处理后,需要根据业务需求调用相应的管理方法:
- 保存更改:如果通过逻辑校验并成功更新了底层数据库(如通过DataAdapter),应调用
dt.AcceptChanges()。这会将所有行的状态重置为Unchanged,清除变更历史。 - 撤销更改:如果在内存中进行了错误操作,可调用
dt.RejectChanges()。这会将 Added 的行移除,Deleted 的行恢复,Modified 的行恢复到Original状态。
以上就是C#获取DataTable变更记录的详细内容,更多关于C#数据操作技术的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









