EF Core 中可以通过
DbContext.Database.GetDbConnection()获取底层的
DbConnection对象,这是访问原生 ADO.NET 连接的入口,常用于执行原生 SQL、手动管理事务或与非 EF 操作集成。
获取连接对象的基本用法
调用
GetDbConnection()不会自动打开连接,它只是返回已配置好的连接实例(如
SqlConnection、
NpgsqlConnection等),是否打开由你控制: 连接通常在首次执行查询或保存时由 EF 自动打开和关闭 若需手动操作(如复用连接、共享事务),应显式调用
.Open()使用完后建议显式
.Close()或用
using语句确保释放
配合事务使用(推荐方式)
直接操作连接时,若想让 EF 的 SaveChanges 和原生命令共用同一事务,应通过
Database.BeginTransaction()获取事务并传给原生命令:
using var context = new MyDbContext();
using var transaction = context.Database.BeginTransaction();
try
{
// EF 操作
context.Blogs.Add(new Blog { Name = "Test" });
context.SaveChanges();
// 原生 SQL,复用同一事务
using var conn = context.Database.GetDbConnection();
using var cmd = conn.CreateCommand();
cmd.Transaction = transaction.GetDbTransaction(); // 关键:绑定事务
cmd.CommandText = "UPDATE Logs SET Status = 'Processed' WHERE Id = @id";
cmd.Parameters.Add(new SqlParameter("@id", 123));
cmd.ExecuteNonQuery();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
注意连接状态和生命周期
GetDbConnection()返回的是 EF 内部管理的连接引用,不是新创建的连接: 不要对它调用
Dispose()—— EF 会在
DbContext释放时统一处理 多次调用
GetDbConnection()返回的是同一个实例(引用相等) 如果 DbContext 已被释放,再调用会抛出
ObjectDisposedException
获取连接字符串或数据库类型
若只需连接信息而非连接实例,可从
DbContextOptions中提取:
// 示例:获取连接字符串(仅限支持的提供程序)
var connectionString = context.Database.GetConnectionString();
// 判断数据库类型(便于条件逻辑)
if (context.Database.ProviderName.Contains("SqlServer"))
{
// SQL Server 特有逻辑
}
else if (context.Database.ProviderName.Contains("Npgsql"))
{
// PostgreSQL 特有逻辑
}
基本上就这些。关键记住:连接由 EF 管理,你只负责“借用”和正确参与事务,别越权处置。
