今天在改进一下项目的代码时遇到的问题,下面的 DbConnection 类型的变量 conn 是否需要使用 using 进行 dispose
using var conn = _dbContext.Database.GetDbConnection();
await conn.ExecuteAsync(
"[dbo].[brand_clicklog_add]",
new { TargetType = targetType, TargetId = id, Ip },
commandType: CommandType.StoredProcedure);
不能,之前代码试过,如果dispose,会导致当前其他查询报错链接已释放啥的,应该是 getConnection 拿到到是公用到connection
正解,这篇博文 Don’t Dispose Your Own EF Connections 也证实了这一点
保险起见,还是考虑从 EF Core 拿到连接字符串新建一个连接
using var conn = new SqlConnection(_dbContext.Database.GetConnectionString());
await conn.ExecuteAsync(
"[dbo].[brand_clicklog_add]",
new { TargetType = targetType, TargetId = id, Ip },
commandType: CommandType.StoredProcedure);
SQL 查询
DbContext 生存期、配置和初始化
高级性能主题
using (var context = new BloggingContext())
{
var rowsModified = context.Database.ExecuteSql($"UPDATE [Blogs] SET [Url] = NULL");
}
对于大多数数据库,执行数据库操作需要持久连接,而打开和关闭这样的连接可能会非常昂贵。 EF 不实现连接池本身,而是依赖于基础数据库驱动程序(例如 ADO.NET 驱动程序)来管理数据库连接。 连接池是一种客户端机制,可重复使用现有数据库连接,以减少反复打开和关闭连接的开销。 EF 支持的数据库(如 Azure SQL 数据库、PostgreSQL 和其他数据库)通常在这个机制上保持一致,但数据库或环境的特定因素(如资源限制或服务配置)可能会影响池的效率。 通常连接池是默认启用的,任何池配置都必须按照该驱动程序文档在低级别驱动程序层面进行。例如,在使用 ADO.NET 时,通常通过连接字符串来配置最小或最大池大小等参数。
如上文所述,连接池与 EF 的 DbContext 池完全正交:低级别数据库驱动程序池化数据库连接(以避免打开/关闭连接的开销),而 EF 可以池化上下文实例(以避免上下文内存分配和初始化开销)。 无论上下文实例是否被放入连接池,EF 通常在每个操作(例如查询)之前打开连接,并在操作后立即关闭,以使其返回到连接池;这样做是为了避免连接不必要地长时间占用池外资源。
既然用EF了就用DbContext管理数据库连接。