从DataTable中删除特定行

nam*_*mco 69 c# delete-row

我想从DataTable中删除一些行,但它给出了这样的错误,

收集被修改; 枚举操作可能无法执行

我用来删除这段代码,

foreach(DataRow dr in dtPerson.Rows){
    if(dr["name"].ToString()=="Joe")
        dr.Delete();
}
Run Code Online (Sandbox Code Playgroud)

那么,问题是什么以及如何解决?你建议采用哪种方法?

Wid*_*dor 144

如果从集合中删除项目,则该集合已更改,您无法继续通过它进行枚举.

相反,使用For循环,例如:

for(int i = dtPerson.Rows.Count-1; i >= 0; i--)
{
    DataRow dr = dtPerson.Rows[i];
    if (dr["name"] == "Joe")
        dr.Delete();
}
dtPerson.AcceptChanges();
Run Code Online (Sandbox Code Playgroud)

请注意,您正在反向迭代以避免在删除当前索引后跳过一行.

  • 这是不正确的.您_can_使用foreach在删除行时循环遍历表.参见[Steve回答](http://stackoverflow.com/a/13752739/441684). (10认同)
  • 此答案还应包括@bokkie的答案。如果我们稍后使用`DataTable`,它将抛出一个异常。正确的方法是在源“ DataTable”上调用“ Remove()”-“ dtPerson.Rows.Remove(dr)”。 (2认同)

Ste*_*eve 114

在每个人都跳过" 你无法删除枚举中 "之前,你需要先了解DataTables是事务性的,并且在调用AcceptChanges()之前不要在技术上清除更改.

如果在调用Delete时看到此异常,则表示您已处于挂起更改数据状态.例如,如果刚从数据库加载,如果你在foreach循环中,调用Delete会抛出异常.

但!但!

如果从数据库加载行并调用函数' AcceptChanges() ',则将所有这些挂起的更改提交给DataTable.现在,您可以在世界范围内遍历调用Delete()的行列表,因为它只是将行标记为Deletion,但在您再次调用AcceptChanges()之前不会提交.

我意识到这个响应有点陈旧,但我最近不得不处理类似的问题,希望这为未来开发10年代码的开发人员节省了一些痛苦:)


Ps这是Jeff添加的一个简单代码示例:

C#

YourDataTable.AcceptChanges(); 
foreach (DataRow row in YourDataTable.Rows) {
    // If this row is offensive then
    row.Delete();
} 
YourDataTable.AcceptChanges();
Run Code Online (Sandbox Code Playgroud)

VB.Net

ds.Tables(0).AcceptChanges()
For Each row In ds.Tables(0).Rows
    ds.Tables(0).Rows(counter).Delete()
    counter += 1
Next
ds.Tables(0).AcceptChanges()
Run Code Online (Sandbox Code Playgroud)

  • 这是很好的信息.一些示例代码会很好. (4认同)
  • 将 ds.Tables(0).Rows` 中的 `object row_loopVariable` 更改为 ds.Tables(0).Rows` 中的`DataRow 行也更有帮助(我认为) (2认同)
  • 如果我可以百万次投票,我会:) (2认同)
  • Ffs,这在噩梦般的周末部署中拯救了我.你应该得到所有的啤酒! (2认同)

bok*_*kie 15

使用此解决方案:

for(int i = dtPerson.Rows.Count-1; i >= 0; i--) 
{ 
    DataRow dr = dtPerson.Rows[i]; 
    if (dr["name"] == "Joe")
        dr.Delete();
} 
Run Code Online (Sandbox Code Playgroud)

如果要在删除行后使用数据表,则会出现错误.所以你可以做的是:替换dr.Delete();dtPerson.Rows.Remove(dr);


Bal*_*dar 13

这对我有用,

List<string> lstRemoveColumns = new List<string>() { "ColValue1", "ColVal2", "ColValue3", "ColValue4" };
List<DataRow> rowsToDelete = new List<DataRow>();

foreach (DataRow row in dt.Rows) {
    if (lstRemoveColumns.Contains(row["ColumnName"].ToString())) {
        rowsToDelete.Add(row);
    }
}

foreach (DataRow row in rowsToDelete) {
    dt.Rows.Remove(row);
}

dt.AcceptChanges();
Run Code Online (Sandbox Code Playgroud)


小智 9

DataRow[] dtr=dtPerson.select("name=Joe");
foreach(var drow in dtr)
{
   drow.delete();
}
dtperson.AcceptChanges();
Run Code Online (Sandbox Code Playgroud)

我希望它会对你有所帮助

  • 命令是 `drow.Delete();` 而不是 `drow.delete();` 方法在 .net 中区分大小写 (2认同)

Kar*_*n P 6

要删除整个行数据表中,做这样的

DataTable dt = new DataTable();  //User DataTable
DataRow[] rows;
rows = dt.Select("UserName = 'KarthiK'");  //'UserName' is ColumnName
foreach (DataRow row in rows)
     dt.Rows.Remove(row);
Run Code Online (Sandbox Code Playgroud)