3

This is my code to remove row from datatable:

DataTable dtapple = dt;

foreach (DataRow drapplicant in dtapple.Rows)
{
    int iapp = Convert.ToInt32(drapplicant["SrNo"].ToString());

    if (drapplicant["PassportExpDate"].ToString().Trim() != "")
    {
        //ViewState["iapp"] = drapplicant;
        dtapple.Rows.Remove(drapplicant);
    }
}

Now when I use above code the row is removed, but after that I get an error

Collection was modified; enumeration operation might not execute

I don't know exact reason.

t3chb0t
  • 16,340
  • 13
  • 78
  • 118
Bhupendra
  • 350
  • 3
  • 16
  • possible duplicate of [Error in datarow,Collection was modified; enumeration operation might not execute](http://stackoverflow.com/questions/15457571/error-in-datarow-collection-was-modified-enumeration-operation-might-not-execut) – صفي Jan 03 '15 at 07:28
  • The solution in the linked question is horrible. With temp DataTables and nested loops :-\ – t3chb0t Jan 03 '15 at 08:25
  • Well, have you solved it yet? – t3chb0t Jan 09 '15 at 09:21

3 Answers3

3

You get this error because a collection must not change while iterating it. To remove some items from a collection you usually need a second collection that you iterate without changing it.

For your DataTable you need to get the rows you want to remove first and put them in a new collection. One way to achieve this is with LINQ:

Let's create some test data:

DataTable dt = new DataTable();
dt.Columns.Add("Test", typeof(bool));
DataRow dr1 = dt.NewRow();
DataRow dr2 = dt.NewRow();
DataRow dr3 = dt.NewRow();

dr1["Test"] = true;
dr2["Test"] = false;
dr3["Test"] = false;

dt.Rows.Add(dr1);
dt.Rows.Add(dr2);
dt.Rows.Add(dr3);

then only get rows where value in the Test column is false and put them in a List<DataRow>:

var removeRows = 
    dt
    .AsEnumerable()
    .Where(r => (bool)r["Test"] == false)
    .ToList();

now you can itereate the new removeRows list and remove its items from the first collection (here DataTable.Rows)

// Remove selected rows.
foreach (var row in removeRows)
{
    dt.Rows.Remove(row);
}

In your this query should work:

var removeRows = 
    dtapple
    .AsEnumerable()
    .Where(r => string.IsNullOrEmpty(r["PassportExpDate"].ToString()) == false)
    .ToList();

If you use string.IsNullOrEmpty() there's no need to Trim() it.

t3chb0t
  • 16,340
  • 13
  • 78
  • 118
0

Try this :

for (int i = 0; i < dataTable.Rows.Count; i++)
{
    var tempRow = dataTable.Rows[i];
    var temp = dataTable.Rows[i][0];
    for (int j = 0; j < dataTable.Rows.Count; j++)
    {
        DataRow rows = dataTable.Rows[j];
        if (temp == rows[0].ToString())
        {
            tempdatatable.Rows.Add(tempRow[0], tempRow[1]);
            dataTable.Rows.Remove(rows);      //Update happen here
        }
        tempdatatable.DefaultView.Sort = "gscitations DESC";
        dataGridView1.DataSource = tempdatatable;
    }
}
صفي
  • 1,068
  • 2
  • 15
  • 34
0

Below code works for me :

for (int i = 0; i < dataTable.Rows.Count; i++)
{
    var tempRow = dataTable.Rows[i];
    var temp = dataTable.Rows[i][0];
    for (int j = 0; j < dataTable.Rows.Count; j++)
    {
        DataRow rows = dataTable.Rows[j];
        if (temp == rows[0].ToString())
        {
            tempdatatable.Rows.Add(tempRow[0], tempRow[1]);
            dataTable.Rows.Remove(rows);      //Update happen here
        }
        tempdatatable.DefaultView.Sort = "gscitations DESC";
        dataGridView1.DataSource = tempdatatable;
    }
}
Bhupendra
  • 350
  • 3
  • 16