每次使用 Dapper 访问数据库时确保数据库连接打开和关闭
Ensuring the database connection opens and closes every time I use Dapper to access the database
这是我目前在我的一个存储库中所做的事情 类:
private IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString);
public IEnumerable<Product> GetProducts(int categoryId = null, bool? active = null)
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("SELECT * ");
sql.AppendLine("FROM Product ");
sql.AppendLine("WHERE @CategoryId IS NULL OR CategoryId = @CategoryId ");
sql.AppendLine(" AND @Active IS NULL OR Active = @Active");
return this.db.Query<Product>(sql.ToString(), new { CategoryId = categoryId, Active = active }).ToList();
}
我想做的一件事是将 IDbConnection 属性 放在我所有其他存储库继承自的 BaseRepository 中。我该怎么做才能确保我的数据库连接在我的每个数据访问函数中正确打开和关闭,如上面的示例?这是我目前使用 Entity Framework 所做的(每个函数都有一个 using 语句,但现在我将 DAL 切换为使用纯 Dapper:
using (var context = new MyAppContext())
{
var objList = (from p in context.Products
where (categoryId == null || p.CategoryId == categoryId) &&
(active == null || p.Active == active)
select p).ToList();
return objList;
}
我注意到在 Dapper examples 中,所有内容都像我期望的那样包装在 using 语句中,但偶尔我会看到它们将它们的函数包装在下面的 using 中:
using (var connection = Program.GetClosedConnection())
GetClosedConnection() returns一个新的SqlConnection,但是两者有什么区别呢?
public static SqlConnection GetOpenConnection(bool mars = false)
{
var cs = connectionString;
if (mars)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
scsb.MultipleActiveResultSets = true;
cs = scsb.ConnectionString;
}
var connection = new SqlConnection(cs);
connection.Open();
return connection;
}
public static SqlConnection GetClosedConnection()
{
return new SqlConnection(connectionString);
}
以下是我一直以来的做法:
SqlConnection dbConnection;
using (dbConnection = new SqlConnection(connectionString))
{
/*
Whatever Dapper stuff you want to do. Dapper will open the
connection and the using will tear it down.
*/
}
至于问题的第二部分,GetClosedConnection
只是实例化一个 SqlConnection
对象,而 GetOpenConnection
实例化 并打开 一个 SqlConnection
对象。您(或 Dapper)将不得不在 GetClosedConnection
.
返回的对象上手动调用 Open()
此答案将根据您的意愿 "avoid repitition"。
对 Dapper 进行扩展 class 并将函数放入其中并使用它。像这样:
public IEnumerable<T> Query<T>(string sqlQuery, object parameters = null)
{
this.activeConnection.Open();
var result = this.activeConnection
.Query<T>(sqlQuery, parameters);
this.activeConnection.Close();
return result;
}
并在 class 的顶部放一个
public SqlConnection activeConnection { get; private set; }
它总是在 class 的构造函数中设置。
这是我目前在我的一个存储库中所做的事情 类:
private IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString);
public IEnumerable<Product> GetProducts(int categoryId = null, bool? active = null)
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("SELECT * ");
sql.AppendLine("FROM Product ");
sql.AppendLine("WHERE @CategoryId IS NULL OR CategoryId = @CategoryId ");
sql.AppendLine(" AND @Active IS NULL OR Active = @Active");
return this.db.Query<Product>(sql.ToString(), new { CategoryId = categoryId, Active = active }).ToList();
}
我想做的一件事是将 IDbConnection 属性 放在我所有其他存储库继承自的 BaseRepository 中。我该怎么做才能确保我的数据库连接在我的每个数据访问函数中正确打开和关闭,如上面的示例?这是我目前使用 Entity Framework 所做的(每个函数都有一个 using 语句,但现在我将 DAL 切换为使用纯 Dapper:
using (var context = new MyAppContext())
{
var objList = (from p in context.Products
where (categoryId == null || p.CategoryId == categoryId) &&
(active == null || p.Active == active)
select p).ToList();
return objList;
}
我注意到在 Dapper examples 中,所有内容都像我期望的那样包装在 using 语句中,但偶尔我会看到它们将它们的函数包装在下面的 using 中:
using (var connection = Program.GetClosedConnection())
GetClosedConnection() returns一个新的SqlConnection,但是两者有什么区别呢?
public static SqlConnection GetOpenConnection(bool mars = false)
{
var cs = connectionString;
if (mars)
{
SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
scsb.MultipleActiveResultSets = true;
cs = scsb.ConnectionString;
}
var connection = new SqlConnection(cs);
connection.Open();
return connection;
}
public static SqlConnection GetClosedConnection()
{
return new SqlConnection(connectionString);
}
以下是我一直以来的做法:
SqlConnection dbConnection;
using (dbConnection = new SqlConnection(connectionString))
{
/*
Whatever Dapper stuff you want to do. Dapper will open the
connection and the using will tear it down.
*/
}
至于问题的第二部分,GetClosedConnection
只是实例化一个 SqlConnection
对象,而 GetOpenConnection
实例化 并打开 一个 SqlConnection
对象。您(或 Dapper)将不得不在 GetClosedConnection
.
Open()
此答案将根据您的意愿 "avoid repitition"。
对 Dapper 进行扩展 class 并将函数放入其中并使用它。像这样:
public IEnumerable<T> Query<T>(string sqlQuery, object parameters = null)
{
this.activeConnection.Open();
var result = this.activeConnection
.Query<T>(sqlQuery, parameters);
this.activeConnection.Close();
return result;
}
并在 class 的顶部放一个
public SqlConnection activeConnection { get; private set; }
它总是在 class 的构造函数中设置。