从DataTable删除行时出现Collection was modified错误的技术求助
解决DataTable遍历删除行时的System.InvalidOperationException错误
你猜的没错,报错根源就是在foreach遍历dtM1.Rows的同时直接删除行——foreach依赖的枚举器是基于集合原始状态创建的,一旦集合被修改(比如删除元素),枚举器就会失效,抛出这个异常。
下面是几种正确的解决方式:
方法1:倒序遍历行集合
倒序遍历的时候,删除当前行不会影响还没遍历到的行的索引(因为是从最后一行往前遍历),避免枚举器失效:
for (int i = dtM1.Rows.Count - 1; i >= 0; i--) { DataRow dr = dtM1.Rows[i]; string id = dr["cmoOrganizationID"].ToString(); bool isMatch = false; foreach (DataRow dr2 in dtSQLite.Rows) { if (dr2["sSupplierID"].ToString() == id) { isMatch = true; break; // 找到匹配就停止遍历,优化性能 } } if (isMatch) { dtM1.Rows.Remove(dr); MessageBox.Show("Item to remove" + id); } } dgv.DataSource = dtM1;
方法2:先收集要删除的行,再批量删除
遍历的时候只记录需要删除的行,不直接修改原集合,最后统一删除:
List<DataRow> rowsToRemove = new List<DataRow>(); foreach (DataRow dr in dtM1.Rows) { string id = dr["cmoOrganizationID"].ToString(); bool isMatch = false; foreach (DataRow dr2 in dtSQLite.Rows) { if (dr2["sSupplierID"].ToString() == id) { isMatch = true; break; } } if (isMatch) { rowsToRemove.Add(dr); MessageBox.Show("Item to remove" + id); } } // 批量删除 foreach (DataRow dr in rowsToRemove) { dtM1.Rows.Remove(dr); } dgv.DataSource = dtM1;
方法3:用LINQ筛选生成新DataTable(推荐)
这种方式更简洁高效,尤其适合数据量较大的场景。先把dtSQLite的ID提取到HashSet(查找效率远高于遍历),再筛选出不需要删除的行生成新表:
// 提取所有需要匹配的ID到HashSet HashSet<string> supplierIds = new HashSet<string>( dtSQLite.Rows.Cast<DataRow>().Select(r => r["sSupplierID"].ToString()) ); // 筛选出不匹配的行,生成新DataTable DataTable filteredDt = dtM1.AsEnumerable() .Where(dr => !supplierIds.Contains(dr["cmoOrganizationID"].ToString())) .CopyToDataTable(); // 绑定新表到DataGridView dgv.DataSource = filteredDt;
内容的提问来源于stack exchange,提问作者Yippiekaiaii
相关产品推荐
相关产品推荐

