You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataGridView插入行触发异常:Collection was modified; enumeration operation might not execute

解决遍历DataTable时插入行引发的集合修改异常

你遇到的Collection was modified; enumeration operation might not execute异常,核心原因是:foreach遍历dt.Rows时,枚举器会锁定集合结构,不允许遍历过程中添加/删除元素(修改集合大小),而你在循环里调用dt.Rows.InsertAt直接修改了集合,触发了这个检查。

以下是两种可行的解决方法:

方法1:反向for循环遍历

使用for循环从最后一行往前遍历,插入新行不会影响未遍历的行索引,同时避开枚举器的集合修改限制:

void connecttosql()
{
    dataGridView1.DataSource = null;
    dataGridView1.Rows.Clear();
    SqlConnection cn = new SqlConnection();
    SqlCommand cmd = new SqlCommand();
    cn.ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True";
    cmd.Connection = cn;
    cmd.Connection.Open();
    cmd.CommandText = $"SELECT lot,item,toleranceMin,toleranceNom,toleranceMax,concernepar,donnees{comboBox1.Text+comboBox2.Text},{comboBox1.Text+comboBox2.Text} FROM Tolerance where {comboBox1.Text+comboBox2.Text} != ''";
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    DataTable dt = new DataTable();
    da.Fill(dt);

    DataColumn col = dt.Columns[$"donnees{comboBox1.Text + comboBox2.Text}"];
    // 反向遍历行集合
    for (int i = dt.Rows.Count - 1; i >= 0; i--)
    {
        DataRow row = dt.Rows[i];
        string a = row[col].ToString();
        
        // 安全转换整数,避免格式异常
        if (int.TryParse(a, out int value) && value > 3)
        {
            DataRow row1 = dt.NewRow();
            // 插入到当前行的下一个位置
            dt.Rows.InsertAt(row1, i + 1);
        }
    }

    BindingSource source = new BindingSource();
    source.DataSource = dt;
    dataGridView1.DataSource = source;
}

方法2:先记录插入位置,再批量插入

先遍历一次DataTable,把所有需要插入行的位置存起来,再倒序批量插入(倒序是为了避免前面的插入操作导致后续位置偏移):

void connecttosql()
{
    dataGridView1.DataSource = null;
    dataGridView1.Rows.Clear();
    SqlConnection cn = new SqlConnection();
    SqlCommand cmd = new SqlCommand();
    cn.ConnectionString = @"Data Source=(LocalDB)\MSSQLLocalDB;Integrated Security=True";
    cmd.Connection = cn;
    cmd.Connection.Open();
    cmd.CommandText = $"SELECT lot,item,toleranceMin,toleranceNom,toleranceMax,concernepar,donnees{comboBox1.Text+comboBox2.Text},{comboBox1.Text+comboBox2.Text} FROM Tolerance where {comboBox1.Text+comboBox2.Text} != ''";
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    DataTable dt = new DataTable();
    da.Fill(dt);

    List<int> insertPositions = new List<int>();
    DataColumn col = dt.Columns[$"donnees{comboBox1.Text + comboBox2.Text}"];

    // 第一次遍历,记录所有需要插入的位置
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        DataRow row = dt.Rows[i];
        string a = row[col].ToString();
        if (int.TryParse(a, out int value) && value > 3)
        {
            insertPositions.Add(i + 1);
        }
    }

    // 倒序插入,避免位置偏移
    foreach (int pos in insertPositions.OrderByDescending(p => p))
    {
        DataRow row1 = dt.NewRow();
        dt.Rows.InsertAt(row1, pos);
    }

    BindingSource source = new BindingSource();
    source.DataSource = dt;
    dataGridView1.DataSource = source;
}

额外优化建议

  • 替换int.Parse为int.TryParse:避免当a不是有效整数字符串时抛出格式异常,提升代码健壮性。
  • 保留BindingSource的使用:用它作为DataGridView的数据源,后续数据变更时能自动同步UI,比直接绑定DataTable更灵活。

内容的提问来源于stack exchange,提问作者LiterallyGutsFromBerserk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 09:37:03