公司数据量已经达到亿级别,原有的单库主从方案不能满足使用了,所以我们进行了分库分表。分库造成原来项目直接注入DbContext的模式无法使用。现在数据连接字符串是根据请求的主体变动的,不能像以前那样直接构造函数注入。
工厂方法
所以,我们考虑使用工厂方法,根据请求主体生成不同的数据库连接。
这里我们使用了IHttpContextAccessor来获取请求上下文,然后根据请求上下文生成数据库连接,ConnectionFactory工厂代码如下
//构造函数public ConnectionFactory(IHttpContextAccessor accessor){ string conStr;#if DEBUG conStr = ConfigurationManager.GetValue("ConnectionString");#else conStr = accessor.GetConnectionString();#endif Connection = string.IsNullOrEmpty(conStr) ? new MySqlConnection(ConfigurationManager.GetValue("ConnectionString")) : new MySqlConnection(conStr);}////// 根据传入字符串更改连接/// /// ///public MySqlConnection ExchangeConnection(string connectionStr){ Connection=new MySqlConnection(connectionStr); return Connection;}//对外公开的连接public MySqlConnection Connection { get; set; }
使用方法
直接注入工厂,然后获取Connection属性
private readonly IDbConnection _connection;public CallHistoryRepository(ConnectionFactory connectionFactory){ _connection = connectionFactory.Connection;}
在startup中注册Scoped类型的注入
services.AddScoped();
遇到的问题
我们有些场景需要更换使用的数据库连接,但是如果我们使用ExchangeConnection方法,那么工厂方法里面的连接是改变成最新的了,但是类中的私有变量IDbConnection _connection引用的还是构造函数注入的老的数据库连接,这时候可以考虑使用懒加载,如下
private readonly Lazy_connectionLazy;public CallHistoryRepository(ConnectionFactory connectionFactory){ _connectionLazy = new Lazy (()=>connectionFactory.Connection);}
这样,无论你在service层更改几次对应的数据库连接,仓储层都会使用最新的连接,完成特定操作。