在ForEach中安全删除DataRow

Jac*_*ada 38 c# collections datatable ado.net datarow

我不明白为什么这段代码不起作用.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)

VMA*_*Atm 51

最安全的方式 - 使用for循环

for (int i = datatable.Rows.Count - 1; i >= 0; i--) 
{
    if (true)
    {
        datatable.Rows[i].Delete();
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记AcceptChanges删除所有标记的行:

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

  • +1比创建另一个副本并进行更改更好. (6认同)
  • `if (true)` 是要检查的占位符,是否需要删除该行。否则数据表中的所有行都将被删除 (2认同)

Jon*_*eet 31

.NET中的大多数集合都不允许您在迭代它时更改集合的内容.来自以下文档DataRow.Delete:

只要集合保持不变,枚举器仍然有效.如果对集合进行了更改,例如添加,修改或删除元素,则枚举数将无法恢复,并且下一次调用MoveNext或Reset会引发InvalidOperationException.如果在MoveNext和Current之间修改了集合,则Current返回它所设置的元素,即使枚举器已经失效.

最好的解决方案通常是创建一个单独的集合(例如a List<DataRow>)要删除的项目,然后在完成迭代后删除它们.

  • @CeeMcSharpface:这意味着“删除不会修改集合的状态,删除不会修改集合的状态”。 (2认同)

Thi*_*ise 19

在使用foreach语句对其进行迭代时,无法修改集合.

你可以试试这样的东西:

List<DataRow> deletedRows = new List<DataRow>();

foreach (DataRow dataRow in dataTable.Rows)
{
    if(true) deletedRows.Add(dataRow);
}

foreach(DataRow dataRow in deletedRows)
{
    dataRow.Delete();
}
Run Code Online (Sandbox Code Playgroud)

  • 不正确.使用"foreach"迭代它时,无法修改集合.您可以使用标准的"for"循环.例如:`for(int i = datatable.Rows.length - 1; i> = 0; i - ){// remove rows}` (6认同)

小智 8

如果调用delete方法,则只需AcceptChanges()在foreach循环后调用要修改的表.

foreach (DataRow dataRow in dataTable.Rows)
{
    if (true)
    {
        dataRow.Delete();
    }
}

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

delete方法只是标记要删除的行.

http://msdn.microsoft.com/en-us/library/system.data.datarow.delete%28v=VS.90%29.aspx


小智 5

可能我的答案不再有用。Foreach 和 DataRow 中抛出的异常仅出现在 .Net 2.0 及更早版本中,原因是 msdn http://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80 ) 的描述).aspx

如果该行的 RowState 为“已添加”,则该行将从表中删除。

使用Delete方法后,RowState将变为Deleted。在您调用 AcceptChanges 之前,它会保持已删除状态。

可以通过调用 RejectChanges 取消删除已删除的行。

要解决这个问题,您可以在使用 foreach 之前调用 DataTable.AcceptChanges()