11

データ行が更新される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;
  }
}
4

3 に答える 3

10

foreachステートメントのバックグラウンドで発生している列挙子(MDSNリンク)を使用してコレクションを列挙している間は、コレクションを変更できません。

この問題を解決する1つの可能な方法は、最初の列挙で削除する行を収集してから、次のように別のループでそれらを削除することです。

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

foreachループをに置き換えることもできforますが、要素を削除するときに現在のインデックスを適切に処理するために追加の作業を行う必要があります。

于 2013-03-17T04:58:41.340 に答える
4

これを試して :

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;
    }
}
于 2013-03-17T04:59:29.783 に答える
0

別のエントリテーブルを作成し、datatable.Rows.Remove(rows)を呼び出す代わりに、この別のテーブルに行「rows」を追加する必要があると思います。次に、1つまたは複数の行が繰り返されるたびに、ifステートメントを実行して、それが「削除された」かどうか、つまり削除された行のリストにあるかどうかを確認します。列挙が終了したら、それらの行をテーブルから完全に削除できます。

編集:

コードの実装は次のとおりです。

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

一意のキーがない場合は、に切り替え!duplicates.Rows.Contains(/*specific row*/)てみてくださいduplicates.Rows.IndexOf(/*specific row*/)>0。それは適切な代替品を提供するはずです。

于 2013-03-17T05:12:56.933 に答える