同一个连接应该注入到多个仓库中,还是在每个调用的方法中打开一个新连接?

3

我有一个视图需要从我的系统中的多个存储库中填充信息。

var employee = employeeRepository.GetEmployeeById(20);
var notes = notesRepository.GetNotes();

我正在使用ADO.NET进行数据访问。每个存储库是否应该将连接作为参数传入?

using(var connection = dbFactory.GetConnection())
{    
    var employeeRepository = new EmployeeRepository(connection);
    var notesRepository = new NotesRepository(connection);
}

或者,每个Get方法是否应该在方法内打开和关闭连接?我已经计时过,在整个过程中使用单个传递的连接速度更快。虽然不是非常明显,但我现在更关心正确的方法。
此外,反复打开和关闭连接对数据库有什么影响?

我认为这个问题的常见解决方案是每个工作单元创建一个连接。如果一个操作需要多个数据库调用,它们将共享连接。如果一个工作单元只需要一个数据库调用,则使用一个连接进行该调用。请搜索“工作单元模式”并查看前两个链接。 - Bob Horn
1个回答

1
ADO.NET使用连接池来提高性能(对于SQL Server而言是这样,查看您的数据库供应商文档以确认它是否支持连接池)。因此,当您创建新的SqlConnection时,您实际上没有打开到数据库的物理连接。您只是从连接池中获取现有的连接。当您在现有连接上调用.Dispose时,您实际上没有关闭到数据库的物理连接。您只是将此连接返回给连接池,以便可以重复使用该连接。

因此,每次您想要向数据库发送查询时,都可以安全地编写以下代码:

using (var conn = new SqlConnection(ConnectionString))
using (var cmd = conn.CreateCOmmand())
{
    // no, you are not opening a real connection here, you are just drawing one from the pool
    conn.Open();
    cmd.CommandText = "SELECT ....";
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            // ...
        }
    }
} // No, you are not closing the connection here, you are simply returning it to the pool

基本上,如果您的 ADO.NET 提供程序支持连接池(通常所有受尊敬的提供程序都应该支持),您不需要存储任何 SQL 连接的引用。只需调用构造函数并传递连接字符串即可。因此,连接字符串是您所需的全部内容。

备注:连接池是按 AppDomain 和连接字符串进行管理的。这意味着,如果您有两个不同的连接字符串连接到同一个数据库,并将这两个连接字符串传递给不同的 SQL 连接实例,则会针对每个连接字符串获得一个连接池(即 2 个连接池)。


这是DB独立的吗?我们正在使用SQLBase(不是出于选择),他们刚刚发布了完全托管的.NET数据提供程序。连接池仍然存在吗? - sinclairchase
我不知道SQLBase是什么。你应该阅读他们的文档,看看你正在使用的ADO.NET提供程序是否支持连接池。 - Darin Dimitrov
1
@DarinDimitrov 如果我需要在同一事务中执行不同存储库的不同方法,那么我应该将事务对象Conexion.BeginTransaction(IsolationLevel.ReadCommitted)注入到这些存储库中吗? - eddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接