You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过GetChanges()返回的DataTable访问原DataTable对应行以实现单条数据撤销?

如何通过GetChanges()返回的DataTable访问原DataTable对应行以实现单条数据撤销?

这个问题我之前也踩过坑,太懂你的无奈了——GetChanges返回的是原表的副本表,直接对副本里的行调用RejectChanges完全不影响原表;而且用Rows.Find找原行还找不到,因为默认查找的是Current版本的行,而标记为Deleted的行在Current版本里相当于“隐身”了。

咱们一步步解决这个问题:

核心问题拆解

  • 副本行不关联原表:GetChanges(DataRowState.Deleted)返回的DataTable里的行是原行的拷贝,对它做任何操作都只会修改副本,和原表的行没关系,所以你之前的r.RejectChanges()根本不会作用到原数据上。
  • Find方法的局限性:Rows.Find默认是基于Current版本的值查找行,但Deleted行的Current版本已经被标记为删除,所以用Original版本的主键值去Find,自然找不到对应的行。

正确的解决方案

我们需要在原表中精准定位到标记为Deleted的行,这里有两种可靠的方式:

方法一:使用DataTable.Select(高效适合大量数据)

利用Select方法可以指定查找的行状态,直接筛选出原表中Deleted状态且主键匹配的行:

DataTable originalTable = GetTable();
DataTable del = originalTable.GetChanges(DataRowState.Deleted);
if (del != null)
{
    foreach (DataRow r in del.Rows)
    {
        // 获取副本行中原版本的主键值(这是删除前行的主键)
        var originalId = r["id", DataRowVersion.Original];
        
        // 注意:如果主键是字符串类型,要给值加单引号,比如 $"id = '{originalId}'"
        string filter = $"id = {originalId}";
        // 在原表中筛选Deleted状态、主键匹配的行
        DataRow[] foundRows = originalTable.Select(filter, "", DataViewRowState.Deleted);
        
        if (foundRows.Length > 0)
        {
            // 对原表的行执行撤销删除操作
            foundRows[0].RejectChanges();
        }
    }
}

方法二:使用LINQ遍历筛选(更直观,适合小数据量)

如果你的数据量不大,用LINQ遍历原表的行,直接匹配状态和原版本主键值也很方便:

DataTable originalTable = GetTable();
DataTable del = originalTable.GetChanges(DataRowState.Deleted);
if (del != null)
{
    foreach (DataRow r in del.Rows)
    {
        var originalId = r["id", DataRowVersion.Original];
        // 从原表的所有行中找到Deleted状态、原版本主键匹配的行
        DataRow originalRow = originalTable.Rows.Cast<DataRow>()
            .FirstOrDefault(row => row.RowState == DataRowState.Deleted 
                && row["id", DataRowVersion.Original].Equals(originalId));
        
        originalRow?.RejectChanges();
    }
}

为什么这两种方法能生效?

原表的Rows集合其实包含所有状态的行,包括Deleted,只是默认的DataView会隐藏Deleted行,我们通过指定DataViewRowState.Deleted或者直接判断RowState,就能把这些“隐身”的行找出来;同时我们用的是原版本的主键值来匹配,这和删除前的行主键一致,所以能精准定位到对应的原行。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:20:27