DataTable已删除行异常显示求助:计数含已删行、遍历触发报错
DataTable已删除行未清除、遍历报错的原因分析
核心原因
DataTable的Delete()方法本质是标记行状态为删除,而非立即物理移除行。标记为Deleted的行仍会保留在Rows集合中,因此Row.Count会将其计入总数。当直接遍历Rows集合时,尝试访问已删除行的内容就会触发「Cannot access deleted rows」错误——因为已删除状态的行不允许被正常读取。只有调用AcceptChanges()后,DataTable才会彻底清除这些标记为删除的行。
是否因设置改动导致?
不存在直接控制该行为的DataTable全局设置,但以下改动可能引发该异常:
- 误删/注释了
AcceptChanges()调用:如果之前的代码在删除行后会隐式或显式调用AcceptChanges()(比如通过DataAdapter执行数据库更新后自动触发,或者代码中主动调用),现在这一步缺失就会导致已删除行残留。 - 遍历方式从DataView改为直接遍历DataTable:如果原本是通过设置了
RowStateFilter = DataViewRowState.CurrentRows的DataView来遍历(自动过滤已删除行),后来改成直接遍历DataTable.Rows,就会访问到已删除行触发错误。 - 删除方法从
Remove()改为Delete():DataRowCollection.Remove()是直接物理移除行,不会留下删除标记;如果原本用的是Remove(),后来改成Delete(),就会出现行残留的情况。
解决建议
- 若无需保留删除状态同步到数据库,直接用
DataTable.Rows.Remove(DataRow)或Rows.RemoveAt(int index)删除行,无需调用AcceptChanges()即可立即移除行。 - 若必须使用
Delete()(比如需要和数据库同步修改状态),遍历前过滤行状态:foreach (DataRow rwUpdatedRefs in tblUpdatedRefs.Rows.Cast<DataRow>().Where(r => r.RowState != DataRowState.Deleted)) { // 处理逻辑 } - 确认业务场景是否需要保留删除状态,若不需要,在删除行后主动调用
tblUpdatedRefs.AcceptChanges()清除已标记的行。
内容的提问来源于stack exchange,提问作者David Williamson
相关产品推荐
相关产品推荐

