Josh
Josh

Reputation: 1901

How to properly update a datatable while inside a loop

In my below code I'm comparing values (email addresses) in my Arrarylist (called emails) with values in my Datatable (called dtResult). I was hoping to be able to remove rows from the datatable if it has an email address that is found in the arraylist but I'm starting to think I'm better off creating a new datatable that does not have those rows instead (I just don't know how to do that). Obviously my code below bombs after a row is deleted because it loses its place in the foreach loop. How can I fix this?

Thanks.

foreach (DataRow row in dtResult.Rows)
{
  var tmpl = row[3];
  for (int x = 0; x < emails.Count; x++)  //emails is an ArrayList of email addresses
  {
    string one = emails[x].ToString().ToUpper();
    string two = tmpl.ToString().ToUpper();
    //compare datatable value to arraylist value..
    if (one == two)
    {
      //if they are equal then I want to remove them (or maybe create a new datatable??)
      dtResult.Rows.Remove(row);
      dtResult.AcceptChanges();
    }
  }
}

Upvotes: 0

Views: 2765

Answers (3)

Iggy
Iggy

Reputation: 109

Why don't you do it in two steps?

I didn't try this, so let me know how it goes.

var deleteRows = new List<DataRow>();

then in your loop, instead of deleting the row right away, just add the row to your list:

deleteRows.Add(row);

and after you loop through your database, you loop through the deleteRows list and delete each row one by one.

Upvotes: 1

Brett
Brett

Reputation: 4061

You could go through the DataTable in reverse

for(int i  = dtResult.Rows.Count; i >= 0; i--)
{
     foreach(object email in emails)
     {
          if(email.ToString().ToUpper() == dtResult[i].ToString().ToUpper())
          {
               dtResult.Rows.Remove(dtResult.Rows[i]);
               dtResult.AcceptChanges();
          }
     }
}

Upvotes: 2

mqp
mqp

Reputation: 71945

The easiest way would be to loop through the DataTable backward:

for (int i = dtResult.Rows.Count - 1; i >= 0; i--)
{
    var row = dtResult.Rows[i];
    // ...
}

You also might want to consider whether you can just mark the row state on those rows as deleted (and then observe that status later) instead of actually removing them from the table.

Upvotes: 4

Related Questions