Cannot remove rows from DataTable because "Collection was modified; enumeration operation might not execute"

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

Коллекция была изменена; операция перечисления может не выполняться

I don't know exact reason.

3 ответа

Решение

Ниже код работает для меня:

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

Вы получаете эту ошибку, потому что коллекция не должна изменяться во время итерации. Чтобы удалить некоторые элементы из коллекции, вам обычно требуется вторая коллекция, которую вы выполняете, не меняя ее.

Для тебя DataTable сначала нужно получить строки, которые вы хотите удалить, и поместить их в новую коллекцию. Один из способов добиться этого с LINQ:

Давайте создадим некоторые тестовые данные:

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

тогда только получить строки, где значение в Test столбец false и положить их в List<DataRow>:

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

теперь вы можете повторить новый removeRows перечислить и удалить его предметы из первой коллекции (здесь DataTable.Rows)

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

По вашему этот запрос должен работать:

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

Если вы используете string.IsNullOrEmpty() нет необходимости Trim() Это.

Попробуй это:

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;
    }
}
Другие вопросы по тегам