当将其作为循环运行时,我应该将Open()和Close()置于循环外部还是内部?

时间:2016-03-11 19:12:38

标签: c# sql asp.net sql-server

我有一段代码

        await this._Conn.OpenAsync();
        using (SqlCommand cmd = new SqlCommand("AddOrUpdateAnswer", this._Conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@AnswerVal", Answer.AnswerVal);
            cmd.Parameters.AddWithValue("@QuestionId", Answer.QuestionId);
            cmd.Parameters.AddWithValue("@PartnerId", Answer.PartnerId);
            await cmd.ExecuteNonQueryAsync();
        }
        this._Conn.Close();

目前不在循环中,但现在我想在循环内运行。我的问题是我是否应该像

那样写
        for ( var Answer in Answers )
        {
            await this._Conn.OpenAsync();
            using (SqlCommand cmd = new SqlCommand("AddOrUpdateAnswer", this._Conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@AnswerVal", Answer.AnswerVal);
                cmd.Parameters.AddWithValue("@QuestionId", Answer.QuestionId);
                cmd.Parameters.AddWithValue("@PartnerId", Answer.PartnerId);
                await cmd.ExecuteNonQueryAsync();
            }
            this._Conn.Close();
        }

或者我是否可以像

一样为整个循环打开它
            await this._Conn.OpenAsync();
            for ( var Answer in Answers )
            {
                using (SqlCommand cmd = new SqlCommand("AddOrUpdateAnswer", this._Conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@AnswerVal", Answer.AnswerVal);
                    cmd.Parameters.AddWithValue("@QuestionId", Answer.QuestionId);
                    cmd.Parameters.AddWithValue("@PartnerId", Answer.PartnerId);
                    await cmd.ExecuteNonQueryAsync();
                }
            }
            this._Conn.Close();

为什么或为什么不呢?

2 个答案:

答案 0 :(得分:5)

开启新连接有一定程度的开销,尽管连接池确实可以显着减少开销。

通常最好在循环之前打开一次连接。

如果抛出异常,您当前的代码将永远不会关闭连接。打开连接时应使用using statement,而不是明确关闭它。让IDisposable模式为您处理。

答案 1 :(得分:2)

每次迭代打开和关闭连接都是浪费的重复:

for ( var Answer in Answers )
    {
        await this._Conn.OpenAsync();
        using (SqlCommand cmd = new SqlCommand("AddOrUpdateAnswer", this._Conn))
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("@AnswerVal", Answer.AnswerVal);
            cmd.Parameters.AddWithValue("@QuestionId", Answer.QuestionId);
            cmd.Parameters.AddWithValue("@PartnerId", Answer.PartnerId);
            await cmd.ExecuteNonQueryAsync();
        }
        this._Conn.Close();
    }

如果您考虑所做的任何数据库查询,请打开连接:

await this._Conn.OpenAsync();
// Do what is needed while the connection is open.
// Then close the connection.
this._Conn.Close();

尽量不要将这个问题与在连接打开时你正在做的事情混淆的事实混淆,这恰好是你在连接打开时单独做的事情。

这就像在商店里拿一个苹果而不是拿一篮子苹果。每次你拿一个苹果然后再回到下一个苹果时都没有必要离开商店。