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.
source to share
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;
}
}
source to share
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.
source to share
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;
}
}
source to share