分库情况下的数据库连接注入

  公司数据量已经达到亿级别,原有的单库主从方案不能满足使用了,所以我们进行了分库分表。分库造成原来项目直接注入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);
}

/// <summary>
/// 根据传入字符串更改连接
/// </summary>
/// <param name="connectionStr"></param>
/// <returns></returns>
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<ConnectionFactory>();

遇到的问题

  我们有些场景需要更换使用的数据库连接,但是如果我们使用ExchangeConnection方法,那么工厂方法里面的连接是改变成最新的了,但是类中的私有变量IDbConnection _connection引用的还是构造函数注入的老的数据库连接,这时候可以考虑使用懒加载,如下

private readonly Lazy<IDbConnection> _connectionLazy;
public CallHistoryRepository(ConnectionFactory connectionFactory)
{
    _connectionLazy = new Lazy<IDbConnection>(()=>connectionFactory.Connection);
}

       这样,无论你在service层更改几次对应的数据库连接,仓储层都会使用最新的连接,完成特定操作。

 

posted @ 2019-08-13 17:26  SeedQi  阅读(526)  评论(0编辑  收藏  举报