2

I have a DataSet with several DataTables inside. I'm displaying the DataTables in a ListView (I didn't know about databinding when I wrote the code). Anyway, I would like to remove rows from the DataTables inside the DataSet.

I have tried this:

foreach (DataRow row in dsData.Tables["Table1"].Rows)
  {
     //find the row that contains the username I'm after
     if (item.SubItems[2].Text == row["LoginName"].ToString())            
       {
         dsData.Tables["Table1"].Rows.Remove(row); //<- main code of interest
       }
  }

I've also tried

dsData.Tables["Table1".Rows.Delete(row);

The problem I'm experiencing is that the when you remove a row I get the exception:

Collection was modified; enumeration operation might not execute.

From what I understand it's because when you remove a row from a ListView the row below it moves up and causes all this trouble. The code itself does what it's supposed to but it's not nice to see that exception when when you run it.

I was about to rewrite the whole class with a DataGridView but would rather correct that single line if possible :).

EDIT: I'm not even sure a DataGridView would solve the problem anyway.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user872416
  • 109
  • 1
  • 4
  • 8

5 Answers5

4

change the loop to a for loop counting backwards so you don't get that message.

for(int i = dsData.Tables["TAble1"].Rows; i > 0; i--)
{
     if(item.SubItems[2].Text == dsData.Tables["Table1"].Rows[i - 1]["LoginName"].ToString())
         dsData.Tables["Table1"].Rows.Remove(i - 1)
}
Gambrinus
  • 2,140
  • 16
  • 26
1

Try:

        DataSet dsData = new DataSet();
        List<DataRow> rowsToDelete = new List<DataRow>();

        foreach (DataRow row in dsData.Tables["Table1"].Rows)
        {
            if (item.SubItems[2].Text == row["LoginName"].ToString())
            {
                rowsToDelete.Add(row);
            }
        }

        foreach(DataRow row in rowsToDelete)
        {
            dsData.Tables["Table1"].Rows.Remove(row); 
        }
HABJAN
  • 9,212
  • 3
  • 35
  • 59
1

You need a backwards for loop if you're going to be removing things (explanation of why here)

for (int i = dsData.Tables["Table1"].Rows.Count - 1; i >= 0; i--)
{
    DataRow row = dsData.Tables["Table1"].Rows[i];

    //find the row that contains the username I'm after
    if (item.SubItems[2].Text == row["LoginName"].ToString())            
    {
        dsData.Tables["Table1"].Rows.Remove(row); //<- main code of interest
    }
}
Community
  • 1
  • 1
codeulike
  • 22,514
  • 29
  • 120
  • 167
0

in general you can't remove items from a collection within a loop that is iterating on it what you could do is keep a list of all the row you want to remove (creating it within the loop) and remove all of them OUTSIDE the loop

Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
0

You can't modify a collection that you are iterating though with a foreach loop, from inside the loop. Do this instead:

for (int i = 0; i < dsData.Tables["Table1"].Rows.Count; i++)
  {
     DataRow row = dsData.Tables["Table1"].Rows[i];
     if (item.SubItems[2].Text == row["LoginName"].ToString())            
       {             
         dsData.Tables["Table1"].Rows.Remove(row); //<- main code of interest
       }
  }
Ben Robinson
  • 21,601
  • 5
  • 62
  • 79