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

循环批量插入数据时遇DataReader未关闭错误,求解决方法

解决SqlCommand执行批量插入时的DataReader关联错误

你遇到的错误提示看似和DataReader有关,但实际核心问题是循环中重复向同一个SqlCommand对象添加参数。第一次循环时参数集合添加了@name和@category,第二次循环再次调用AddWithValue会导致参数重复,触发内部执行异常,进而抛出了误导性的DataReader相关错误。

推荐修改方案:预定义参数,循环内赋值

这种方式效率更高,避免重复创建命令对象,同时彻底解决参数重复问题:

List<TransactionAccount> accounts = new List<TransactionAccount>();

try
{
    using (var con = new SqlConnection(connectionString))
    {
        string query = "INSERT INTO Accounts (name, category) VALUES (@name, @category)";
        // 用using包裹SqlCommand,确保资源自动释放
        using (var cmd = new SqlCommand(query, con))
        {
            // 预先定义参数并指定类型(比AddWithValue更安全,避免类型推断问题)
            cmd.Parameters.Add("@name", SqlDbType.NVarChar);
            cmd.Parameters.Add("@category", SqlDbType.NVarChar);
            
            con.Open();
    
            foreach (TransactionAccount account in accounts)
            {
                // 循环内仅更新参数值,不重复添加参数
                cmd.Parameters["@name"].Value = account.name;
                cmd.Parameters["@category"].Value = account.category;
                cmd.ExecuteNonQuery();
            }
        }
    }
    // using块会自动关闭连接,无需手动调用con.Close()
}
catch (Exception ex)
{
    // 这里建议添加异常处理逻辑,比如记录日志或输出错误信息
    Console.WriteLine(ex.Message);
}

另一种简单方案:循环内新建SqlCommand

如果不想预定义参数,也可以每次循环创建新的SqlCommand对象(效率略低,但实现简单):

List<TransactionAccount> accounts = new List<TransactionAccount>();

try
{
    using (var con = new SqlConnection(connectionString))
    {
        con.Open();
        string query = "INSERT INTO Accounts (name, category) VALUES (@name, @category)";
    
        foreach (TransactionAccount account in accounts)
        {
            using (var cmd = new SqlCommand(query, con))
            {
                cmd.Parameters.AddWithValue("@name", account.name);
                cmd.Parameters.AddWithValue("@category", account.category);
                cmd.ExecuteNonQuery();
            }
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}

关键注意事项

  • 不要手动调用con.Close():using语句块会自动释放连接资源,无论是否发生异常。
  • 优先避免AddWithValue:该方法可能导致SQL Server的类型推断错误,推荐显式指定参数类型。
  • 用using包裹SqlCommand:确保命令对象的资源被正确释放,避免潜在的资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:15:32