C#中Sql-Connection类的Singleton模式实现及参数传递问题咨询
C# 中 SqlConnection 单例模式实现及参数传递方案
注意:通常不建议直接将SqlConnection封装为全局单例。ADO.NET内置了连接池机制,频繁开闭连接不会造成额外性能开销,全局单例连接反而容易引发多线程冲突、连接超时、事务状态混乱等问题。下述方案仅为单例模式的实践演示,生产环境建议按需创建SqlConnection实例,用完即释放。
基础实现(线程安全+支持配置注入)
我们可以封装一个单例的数据库连接管理器,统一存储连接配置、托管SqlConnection实例:
- 首先定义连接配置实体,用来存储数据库名、默认表名、账号密码等自定义参数
// 需按需引用对应命名空间:System.Data.SqlClient / Microsoft.Data.SqlClient public class DbConnectionConfig { public string ServerAddress { get; set; } public string DatabaseName { get; set; } public string UserName { get; set; } public string Password { get; set; } // 可自定义扩展存储默认表名、连接超时时间等参数 public string DefaultTableName { get; set; } public string BuildConnectionString() { return $"Server={ServerAddress};Database={DatabaseName};User ID={UserName};Password={Password};TrustServerCertificate=True;"; } }
- 实现线程安全的单例连接管理器
public sealed class SingletonDbConnector { // 懒加载实现线程安全的单例实例,避免多线程下重复创建 private static readonly Lazy<SingletonDbConnector> _instance = new Lazy<SingletonDbConnector>(() => new SingletonDbConnector()); // 私有构造函数,禁止外部直接实例化 private SingletonDbConnector() {} public static SingletonDbConnector Instance => _instance.Value; // 全局配置存储字段 private DbConnectionConfig _currentConfig; // 单例托管的SqlConnection实例 private SqlConnection _connection; /// <summary> /// 全局初始化方法,仅需在程序启动时调用1次 /// </summary> /// <param name="config">数据库连接相关配置</param> /// <exception cref="InvalidOperationException">重复初始化会抛出异常</exception> public void Init(DbConnectionConfig config) { if (_currentConfig != null) throw new InvalidOperationException("单例连接管理器已完成初始化,不可重复配置"); _currentConfig = config ?? throw new ArgumentNullException(nameof(config)); _connection = new SqlConnection(_currentConfig.BuildConnectionString()); } /// <summary> /// 获取可用的打开状态数据库连接 /// </summary> public SqlConnection GetActiveConnection() { if (_currentConfig == null) throw new InvalidOperationException("请先调用Init方法初始化连接配置"); if (_connection.State == System.Data.ConnectionState.Closed) { _connection.Open(); } return _connection; } /// <summary> /// 对外暴露全局配置,所有调用方可直接读取数据库名、默认表名等参数 /// </summary> public DbConnectionConfig Config => _currentConfig ?? throw new InvalidOperationException("连接管理器未初始化"); }
使用方法
- 程序启动阶段全局初始化(仅执行1次)
// 例如在Main方法、服务注册环节执行初始化 SingletonDbConnector.Instance.Init(new DbConnectionConfig { ServerAddress = "127.0.0.1", DatabaseName = "SampleDb", UserName = "sa", Password = "your_password", DefaultTableName = "Users" });
- 业务代码中调用
// 任意业务位置都可以直接获取单例实例,无需传递参数 var dbConnector = SingletonDbConnector.Instance; // 直接从单例配置中读取数据库名、表名等参数 string querySql = $"SELECT * FROM {dbConnector.Config.DefaultTableName}"; // 执行SQL逻辑 using var command = new SqlCommand(querySql, dbConnector.GetActiveConnection()); using var dataReader = command.ExecuteReader(); // 后续数据读取逻辑
参数传递说明
- 所有连接相关的自定义参数统一在初始化阶段存入单例的
Config属性,全局所有调用方都可以直接读取,无需重复传参 - 如果需要动态修改数据库、表名等配置,可在单例类中新增线程安全的配置更新方法,更新前需主动关闭已打开的连接,避免状态异常
内容的提问来源于stack exchange,提问作者Mohammad Hujerat
相关产品推荐
相关产品推荐

