Safely Removing DataRow In ForEach

2019-01-22 10:59发布

I don't understand why this code does not work.

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

15条回答
兄弟一词,经得起流年.
2楼-- · 2019-01-22 11:38

This is because it looks like try to disassemble the stair of staircase that you climb. Simply, you cannot remove an item you iterate.

Therefore you should use different array to iterate and remove them from datatable Rows property.

foreach (DataRow dataRow in dataTable.Select())
{
    if (true)
    {
        dataTable.Rows.Remove(dataRow);
    }
}
查看更多
The star\"
3楼-- · 2019-01-22 11:41

There is an other version of it (I think an easier) what I just used:

int i=0;
while (i < myDataTable.Rows.Count)
{
    if (condition)  //should it be deleted?
        myDataTable.Rows.RemoveAt(i);
    else
        i++;
}

This faster.

查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-22 11:44

may be my answer not longer useful. exception throw in Foreach with DataRow only appear in .Net 2.0 and earlier, the reason is description at msdn http://msdn.microsoft.com/en-us/library/system.data.datarow.delete(v=vs.80).aspx

If the RowState of the row is Added, the row is removed from the table.

The RowState becomes Deleted after you use the Delete method. It remains Deleted until you call AcceptChanges.

A deleted row can be undeleted by invoking RejectChanges.

to pass this problem you can call DataTable.AcceptChanges() before using foreach

查看更多
小情绪 Triste *
5楼-- · 2019-01-22 11:46

Only for people who are looking for specific scenario like me, I needed to shorten time taken, and once some useful infomation is extracted from each row, I excluded the row by marking as deleted.

Hope this help someone...

foreach (DataRow dataRow in dataTable.Rows)
{
    if (dataRow.RowState != DataRowState.Deleted)
    {
        if (your condition here)
        {
            dataRow.Delete();
        }
    }
}
查看更多
Deceive 欺骗
6楼-- · 2019-01-22 11:47

Sure Magents

This is how I did it and works fine

dt = GetStationeryConsolidationDetails(txtRefNo.Text);
int intRows = dt.Rows.Count;
int x = 0;
for (int c = 0; c < intRows; c++)
{
  if (dt.Rows[c - x]["DQTY"].ToString() == "0")
  {
    dt.Rows[c - x].Delete();
    dt.AcceptChanges();
    x++;        
  }
}
查看更多
你好瞎i
7楼-- · 2019-01-22 11:50

Most collections in .NET don't allow you to change the contents of the collection while you're iterating over it. From the docs for IEnumerator:

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and the next call to MoveNext or Reset throws an InvalidOperationException. If the collection is modified between MoveNext and Current, Current returns the element that it is set to, even if the enumerator is already invalidated.

The best solution is usually to create a separate collection (e.g. a List<DataRow>) of items you want to remove, and then remove them after you've finished iterating.

查看更多
登录 后发表回答