我正在帮助调试一些代码并使用以下for循环。它是否在每次迭代时打开和关闭与数据库的连接?
for (int i = 0; i < count; i++)
{
int num = dataTable.Rows[i]["Location_Id"]
database.ProcessAlerts("spProcessAlerts", num)
}
从数据库类中,这里是相关部分:
public bool GetConnection()
{
try
{
GeneralLib.GetIniSettings();
string connectionStrings = GeneralLib.Settings.ConnectionStrings;
Database.conn = new SqlConnection(connectionStrings);
Database.conn.Open();
}
...
public void ProcessAlerts(string ProcedureName, int nByLocationId)
{
try
{
if (this.GetConnection())
{
SqlCommand sqlCommand = new SqlCommand(ProcedureName, Database.conn);
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter sqlParameter = sqlCommand.Parameters.Add("@ByLocation_Id", SqlDbType.Int);
sqlParameter.Value = nByLocationId;
sqlCommand.ExecuteNonQuery();
this.CloseConnection();
}
}
我的直觉让我相信for循环在每次迭代时打开/关闭,但由于我根本不和.net合作,所以我真的不知道。我已经对此进行了大量搜索,但未找到满意的答案(例如Execution Time Slower with each Iteration of the same SPROC,Keep Sql Connection open for iterating many requests? Or close each step?,Opening and closing database connection for each query和C# SQLConnection pooling)。有些帖子说要在需要时打开连接并立即关闭,而其他帖子已经说过如果你使用连接池,连接并没有真正关闭,它只是不可用。我不完全理解这一点。
基本上这段代码应该处理信息,以便可以发送警报,并且我们最近在这个过程中遇到了很大的时间延迟。从日志中我可以看到for循环开始/停止的时间,并且有时需要几个小时才能遍历几千条记录。也可能是spProcessAlerts花了很多时间来运行某些行,所以我也在研究那里发生的事情。
答案 0 :(得分:5)
是......而且没有。
ADO.Net使用Connection Pooling.因此,当您反复拨打Connection.Open()
和Connection.Close()
时,ADO.Net 可能只是将您回复给现有的,已经开放的连接。
但我的偏好仍然是在循环之外抽象出那种东西。
答案 1 :(得分:1)
如果您想要像管道这样的单一连接,可以像这样更改代码:
using(var connection= GetConnectionX()){
connection.Open();
for (int i = 0; i < count; i++)
{
int num = dataTable.Rows[i]["Location_Id"]
database.ProcessAlerts("spProcessAlerts", num, connection)
}
}
public SqlServerConnection GetConnectionX()
{
GeneralLib.GetIniSettings();
string connectionStrings = GeneralLib.Settings.ConnectionStrings;
return new SqlConnection(connectionStrings);
}
public void ProcessAlerts(string ProcedureName, int nByLocationId , SqlServerConnection connection)
{
try
{
SqlCommand sqlCommand = new SqlCommand(ProcedureName, connection);
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter sqlParameter = sqlCommand.Parameters.Add("@ByLocation_Id", SqlDbType.Int);
sqlParameter.Value = nByLocationId;
sqlCommand.ExecuteNonQuery();
}
}
答案 2 :(得分:0)
您拥有代码的方式,是的,您似乎每次都要打开一个新连接,但是您不必这样做。
我将GetConnection重写为OpenConnection和CheckConnection,其中OpenConnection设置一个布尔值,CheckConnection只调用OpenConnection,如果该布尔值为false。然后我会在你的for循环上面调用OpenConnection,(我也会在它下面建立一个紧密的连接)