Unable to remove rows from DataTable because "The collection has been modified, the enumeration operation may fail"

This is my code for deleting a 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 the code above the line is removed but after that I get the error

The collection has been changed; enumeration operation may fail

I don't know the exact reason.

+3


source to share


3 answers


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;
    }
}

      

0


source


You are getting this error because the collection shouldn't change when you run it again. To remove some items from a collection, you usually need a second collection that you iterate through without changing it.

For yours, DataTable

you need to first get the lines you want to delete and put them in a new collection. One way to achieve this is with LINQ

:

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 the value in the column Test

is equal false

and put them in List<DataRow>

:

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

      



now you can view the new list removeRows

and remove its items from the first collection (here DataTable.Rows

)

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

      

Your request should work:

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

      

If you are using string.IsNullOrEmpty()

, don't need Trim()

it.

+1


source


Try the following:

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;
    }
}

      

0


source







All Articles