for循环是否在每次迭代时打开和关闭数据库连接?

时间:2014-07-28 22:34:48

标签: c# .net sql-server performance

我正在帮助调试一些代码并使用以下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 SPROCKeep Sql Connection open for iterating many requests? Or close each step?Opening and closing database connection for each queryC# SQLConnection pooling)。有些帖子说要在需要时打开连接并立即关闭,而其他帖子已经说过如果你使用连接池,连接并没有真正关闭,它只是不可用。我不完全理解这一点。

基本上这段代码应该处理信息,以便可以发送警报,并且我们最近在这个过程中遇到了很大的时间延迟。从日志中我可以看到for循环开始/停止的时间,并且有时需要几个小时才能遍历几千条记录。也可能是spProcessAlerts花了很多时间来运行某些行,所以我也在研究那里发生的事情。

3 个答案:

答案 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,(我也会在它下面建立一个紧密的连接)