Hik*_*ari 11 .net c# connection-pooling idisposable sqlconnection
我来自Java经验,我试图从C#开始.我已经阅读了SqlConnection SqlCommand SqlDataReader IDisposable,我可以理解连接到数据库的最佳做法是包装SqlConnection,SqlCommand并SqlDataReader在他们自己的using块中.
但在Java中,我们使用将连接封装到工厂方法中,只创建一次,并将其重用于所有查询,甚至是多线程查询.仅为每个查询创建语句和结果集,并尽快关闭.
是不是SqlConnection为每个查询创建一个新的有点矫枉过正?不能重复使用吗?
Phi*_*ipH 30
创建类的新实例SqlConnection不会创建到SQL Server的新网络连接,而是租用现有连接(或创建新连接)..NET为您处理物理连接池.
完成连接后(通过它可以发送多个查询)Close()或Dispose()(或using{}最好使用块).
缓存SqlConnection类的实例没有必要,也没有好的做法.
MS SQL服务器管理它自己的连接池中的连接,并且它们实际上没有被处理掉.但它们已关闭,因此您可以最小化网络流量并释放与服务器的可用连接.
此外,您应该注意,如果您使用的是Linq-To-SQL,数据上下文在释放之前不会释放连接,因此我建议您只使用已经正常工作的代码而不要尝试自己优化它.
正如 VMAtm 所说,.net 自行池化连接,因此完全可以重新创建它们。因此,我通常会像这样为整个过程编写一个包装器。
public static void RunWithOpenSqlConnection(string connectionString, Action<SqlConnection> connectionCallBack)
{
SqlConnection conn = null;
try
{
conn = new SqlConnection(connectionString);
connectionCallBack(conn);
}
catch (Exception ex)
{
//Log Error Here
}
finally
{
if (conn != null)
conn.Dispose(); //will close the connection
}
}
public static void ExecuteSqlDataReader(string connectionString, string sqlCommand, Action<SqlDataReader> readerCallBack)
{
RunWithOpenSqlConnection(connectionString, delegate(SqlConnection conn)
{
SqlCommand cmd = null;
SqlDataReader reader = null;
try
{
cmd = new SqlCommand(sqlCommand, conn);
reader = cmd.ExecuteReader();
readerCallBack(reader);
}
catch (Exception ex)
{
//Log Error Here
}
finally
{
if (reader != null)
reader.Dispose();
if (cmd != null)
cmd.Dispose();
}
});
}
//Example calling these
ExecuteSqlDataReader(ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString, "Select EmployeeID FROM Employees;", delegate(SqlDataReader reader)
{
List<string> employeeIds = new List<string>();
if (reader.HasRows)
{
while(reader.Read())
{
employeeIds.Add((string)reader[0]);
}
}
});
Run Code Online (Sandbox Code Playgroud)