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

C#.NET Core 5项目SQL Server连接循环数百次后冻结如何解决

问题修复与代码优化方案

已排查到的核心问题

  • SQL语法错误:SELECT子句中group_country_code字段后多了多余的逗号,会直接导致SQL执行失败,触发异常后返回空列表
  • 对象引用错误:循环中反复修改同一个传入的Contract实例属性再添加到列表,最终列表内所有元素都是同一个对象的引用,属性值为最后一次循环的结果,外部修改该对象时会出现全列表属性同步变更,看起来像返回值为空/null
  • SQL注入风险:直接拼接SQL字符串,若Contract.Number含特殊字符(如单引号)会触发SQL语法错误,也存在被注入攻击的风险
  • 空值未处理:数据库字段为DBNull时直接调用ToString()会抛出异常,被catch捕获后方法直接返回空列表
  • 不必要的性能开销:每次调用方法都重新实例化SqlConnectionStringBuilder,无意义的重复初始化会增加性能消耗
  • 冗余的连接关闭操作:using块会在离开作用域时自动释放连接,手动调用Close()反而可能在异常场景下出现不可预期的资源释放问题
  • 查询性能缺陷:like '%xxx'左模糊查询无法走索引,数据量越大查询耗时越长,循环调用累计延迟会表现为连接冻结
  • 类库兼容性问题:System.Data.SqlClient已停止功能更新,对.NET Core 5的兼容性不如微软官方推荐的Microsoft.Data.SqlClient类库,存在已知的连接bug

优化后代码

// 连接字符串构建器静态复用,避免重复初始化
private static readonly SqlConnectionStringBuilder _connBuilder = new SqlConnectionStringBuilder
{
    DataSource = "server01",
    UserID = "user1",
    Password = "SecretPassword",
    InitialCatalog = "archiv1",
    // 新增连接池配置,避免连接池耗尽导致的冻结
    MaxPoolSize = 200,
    ConnectionTimeout = 15
};

public List<Contract> ReadDBView(Contract contract)
{
    List<Contract> contracts = new List<Contract>();
    // 前置参数校验,避免空引用异常
    if (contract == null || string.IsNullOrWhiteSpace(contract.Number?.ToString()))
    {
        return contracts;
    }
    try
    {
        // 修正SQL语法错误,使用参数化查询
        string sql = "SELECT name, group_name, group_country_code FROM [dbo].[GROUPS] where number like @NumberFilter";

        using (SqlConnection connection = new SqlConnection(_connBuilder.ConnectionString))
        {
            connection.Open();
            using (SqlCommand command = new SqlCommand(sql, connection))
            {
                // 添加参数,自动处理特殊字符转义
                command.Parameters.AddWithValue("@NumberFilter", $"%{contract.Number}");
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // 每次循环新建Contract实例,避免引用共用问题
                        var resultContract = new Contract
                        {
                            // 处理DBNull空值
                            DealerName = reader.IsDBNull("name") ? string.Empty : reader["name"].ToString(),
                            GroupName = reader.IsDBNull("group_name") ? string.Empty : reader["group_name"].ToString(),
                            Country = reader.IsDBNull("group_country_code") ? string.Empty : reader["group_country_code"].ToString(),
                            Number = contract.Number
                            // 其他需要赋值的属性按需求补充
                        };
                        contracts.Add(resultContract);
                    }
                }
            }
            // 移除冗余的connection.Close()调用
        }
    }
    catch (SqlException e)
    {
        Console.WriteLine(e.ToString());
        // 可根据业务需求添加日志、重试逻辑
    }
    return contracts;
}

连接冻结问题解决方案

  1. 替换类库:将System.Data.SQLClient 4.8.2替换为最新稳定版的Microsoft.Data.SqlClient,修复.NET Core下的已知连接bug
  2. 优化查询:业务允许的前提下将左模糊查询改为右模糊like 'xxx%',或给number字段添加全文索引,大幅提升查询速度
  3. 并发控制:如果是高频循环调用,建议添加本地缓存,相同Number的查询结果缓存3~5秒,避免重复访问数据库
  4. 异常重试:新增SQL执行失败重试机制,避免网络抖动导致的连接假死
  5. 连接池调整:根据实际并发量调整连接字符串中的Max Pool Size参数,默认值为100,高并发场景可适当调大,避免连接池耗尽导致的请求等待

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:27:01