C# 数据行错误,集合被修改;枚举操作可能不会执行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15457571/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 16:54:05  来源:igfitidea点击:

Error in datarow,Collection was modified; enumeration operation might not execute

c#foreachdatarow

提问by mani

I have for-each loop in which the data row is updated so the exception ,Collection was modified; enumeration operation might not executeis generated. any way to fix it? i have seen To-List function but it is not working with data row , here is my code:

我有 for-each 循环,其中更新了数据行,因此修改了异常Collection;生成的枚举操作可能不会执行。有什么办法解决吗?我见过 To-List 功能,但它不适用于数据行,这是我的代码:

foreach (DataRow row in dataTable.Rows) {
  temp = row[0].ToString();
  foreach (DataRow rows in dataTable.Rows) {
    if (temp == rows[0].ToString()) {
      tempdatatable.Rows.Add(row[0],row[1]);
      dataTable.Rows.Remove(rows);
      //Update happens here
    }
    tempdatatable.DefaultView.Sort = "gscitations DESC";
    dataGridView1.DataSource = tempdatatable;
  }
}

采纳答案by Parimal Raj

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

回答by koss

You cannot modify collection while enumerating it using Enumerator, which is happening behind the scene of the foreachstatement (MDSN link).

您不能在使用 Enumerator 枚举集合时修改集合,这是在foreach语句的幕后(MDSN 链接)发生的。

One possible way to solve this problem is to collect rows to be deleted in the first enumeration and than remove them in the separate loop like this:

解决此问题的一种可能方法是收集要在第一次枚举中删除的行,然后像这样在单独的循环中删除它们:

var rowsToDelete = new List<DataRow>();

foreach (DataRow row in dataTable.Rows)
     {
         temp = row[0].ToString();
         foreach (DataRow rows in dataTable.Rows)
         {
             if (temp == rows[0].ToString())
             {
                 tempdatatable.Rows.Add(row[0],row[1]);
                 rowsToDelete.Add(rows);
             }
             tempdatatable.DefaultView.Sort = "gscitations DESC";
             dataGridView1.DataSource = tempdatatable;
         }
     }

rowsToDelete.ForEach( x => dataTable.Rows.Remove(x) );

You can also replace foreachloop with for, but you need to do extra work properly handling the current index while deleting the elements.

您也可以用 替换foreach循环for,但您需要做额外的工作,在删除元素时正确处理当前索引。

回答by Jsterman

I would say that you should make a separate table of entries, and instead of calling datatable.Rows.Remove(rows), add the row "rows" to this other table. Then, whenever row or rows iterates, you run an if statement to check if its been "deleted", i.e., in the list of deleted rows. After the enumeration is over, you can then delete those rows permanently from the table.

我会说你应该制作一个单独的条目表,而不是调用 datatable.Rows.Remove(rows),将行“行”添加到另一个表中。然后,每当一行或多行迭代时,您运行一个 if 语句来检查它是否已被“删除”,即在已删除行的列表中。枚举结束后,您可以从表中永久删除这些行。

EDIT:

编辑:

Here's the code implementation:

下面是代码实现:

DataTable duplicates = dataTable;
duplicates.Rows.Clear(); /* Produces an empty duplicate of the 
dataTable table to put the duplicates in */
foreach (DataRow row in dataTable.Rows)
{
     if (!duplicates.Rows.Contains(row))
     {    
         temp = row[0].ToString();
         foreach (DataRow rows in dataTable.Rows)
         {
             if (temp == rows[0].ToString()&&!duplicates.Rows.Contains(rows)) //need unique key
             {
                 tempdatatable.Rows.Add(row[0],row[1]);

             }
             tempdatatable.DefaultView.Sort = "gscitations DESC";
             dataGridView1.DataSource = tempdatatable;
         }
    }
}
foreach (DataRow row in duplicates.Rows)
{
    dataTable.Rows.Remove(row);
}

if you don't have a unique key, you can try switching !duplicates.Rows.Contains(/*specific row*/)for duplicates.Rows.IndexOf(/*specific row*/)>0. That should provide an adequate substitute.

如果您没有唯一键,您可以尝试切换!duplicates.Rows.Contains(/*specific row*/)duplicates.Rows.IndexOf(/*specific row*/)>0. 那应该提供一个适当的替代品。