ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

EFCore启用数据库连接池

2022-04-19 10:00:07  阅读:322  来源: 互联网

标签:启用 数据库 DbContext AddPooledDbContextFactory EFCore 连接 连接池


本文环境为.Net5 + ASP.Net Core Web API + EFCore 5.0.12 + MySQL 5,介绍了如何使用EFCore开启数据库连接池。

在实现了自己的DbContext之后,需要在Startup.cs的ConfigureServices方法中注册DbContext。在ASP.Net Core Web API中,每次请求对应的Controller都会创建一次DbContext对象,而普通的注册会在每次创建DbContext对象时连接一次数据库,这样会频繁的连接数据库(然后关闭),很有可能会使数据库的连接资源耗尽。因此,需要使用连接池以便减少数据库的连接次数,使系统更加稳健。

EFCore提供了2种开启数据库连接池的方法,一种是使用IServiceCollection接口的扩展方法AddDbContextPool,该扩展方法注册了DbContext类,可以在Controller中注入DbContext对象;另一种方法是使用IServiceCollection接口的扩展方法AddPooledDbContextFactory,该扩展方法注册了IDbContextFactory接口,可以在Controller中注入IDbContextFactory类型的对象。

2种开启数据库连接池方法的区别是:前者(AddDbContextPool)直接注入DbContext对象,因此在请求建立连接时就进行数据库连接,尽管是使用池种的数据库连接;后者(AddPooledDbContextFactory)对IDbContextFactory进行了单例注册,在需要数据库连接的时候使用CreateDbContext方法建立数据库连接,可视为能够仅在需要请求数据库的时候动态建立数据库连接,灵活性比较大。

针对上述2种方法,AddDbContextPool方法适合在每个请求都需要连接数据库的Controller中使用,AddPooledDbContextFactory方法则没有使用限制,唯一需要注意的是处理好2个关联的需要使用DbContext对象的方法,防止频繁创建DbContext。鉴于此,更推荐使用AddPooledDbContextFactory方法启用数据库连接池。

需要注意的是,在启用数据库连接池的时候,自己实现的DbContext派生类中,构造函数不能有除了DbContextOptions以外的参数,这是因为连接池时DbContext对象会被连接池保存,这意味着DbContext对象是单例的,所以不能有其他注入的服务。参考stackoverflow

此外,数据库连接字符串默认参数是pooling=true,如果改为pooling=false也会对启用数据库连接池造成影响。

1、默认不启用数据库连接池

//注册数据库上下文
services.AddDbContext<MySqlDbContext>();

2、使用AddDbContextPool启用数据库连接池

//注册数据库上下文(启用数据库连接池)
var connectionString = Configuration.GetConnectionString("MySQLConnection");
services.AddDbContextPool<MySqlDbContext>(optionsBuilder =>
        optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)),
    64
);

3、使用AddPooledDbContextFactory启用数据库连接池

//注册数据库上下文(启用数据库连接池)
var connectionString = Configuration.GetConnectionString("MySQLConnection");
services.AddPooledDbContextFactory<MySqlDbContext>(optionsBuilder =>
        optionsBuilder.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)),
    64
);
[Route("api/[controller]")]
[ApiController]
public class ClientsController : ControllerBase
{
    private readonly ILogger<ClientsController> _logger;
    private readonly IDbContextFactory<MySqlDbContext> _dbContextFactory;

    public ClientsController(
        ILogger<ClientsController> logger,
        IDbContextFactory<MySqlDbContext> dbContextFactory
    )
    {
        _logger = logger;
        _dbContextFactory = dbContextFactory;
    }

    [HttpGet("count")]
    public async Task<IActionResult> GetCountAsync()
    {
        try
        {
            using (var dbContext = _dbContextFactory.CreateDbContext())
            {
                var count = await dbContext.Clients.CountAsync();
                return Ok(count);
            }
        }
        catch (Exception e)
        {
            var message = $@"GetCountAsync failed:{e.Message}.";
            _logger.LogError(message);
            return Problem(message);
        }
    }
}

标签:启用,数据库,DbContext,AddPooledDbContextFactory,EFCore,连接,连接池
来源: https://www.cnblogs.com/xhubobo/p/16163949.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有