SqlCommand.Dispose закрывает соединение? - PullRequest
51 голосов
/ 14 сентября 2008

Могу ли я эффективно использовать этот подход?

using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
    cmd.Connection.Open();
    // set up parameters and CommandType to StoredProcedure etc. etc.
    cmd.ExecuteNonQuery();
}

Меня беспокоит: закроет ли метод Dispose SqlCommand (который вызывается при выходе из блока using) базовый объект SqlConnection или нет?

Ответы [ 3 ]

105 голосов
/ 14 сентября 2008

Нет, удаление SqlCommand не повлияет на соединение. Лучшим подходом было бы также обернуть SqlConnection в блок использования:

using (SqlConnection conn = new SqlConnection(connstring))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
    {
        cmd.ExecuteNonQuery();
    }
}

В противном случае Соединение не изменяется из-за того, что использовавшая его Команда была удалена (возможно, это то, что вы хотите?). Но имейте в виду, что соединение должно быть уничтоженным, и, вероятно, более важным, чем команда.

РЕДАКТИРОВАТЬ:

Я только что проверил это:

SqlConnection conn = new SqlConnection(connstring);
conn.Open();

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn))
{
    Console.WriteLine(cmd.ExecuteScalar().ToString());
}

conn.Dispose();  

Первая команда была удалена при выходе из блока использования. Соединение было все еще открыто и хорошо для второй команды.

Таким образом, удаление команды определенно не избавляет от используемого соединения.

10 голосов
/ 09 октября 2008

SqlCommand.Dispose будет недостаточно, поскольку многие SqlCommand (s) могут (повторно) использовать один и тот же SqlConnection. Сосредоточьте свое внимание на SqlConnection.

0 голосов
/ 13 апреля 2011

Я использую этот шаблон. У меня есть этот частный метод в моем приложении:

private void DisposeCommand(SqlCommand cmd)
{
    try
    {
        if (cmd != null)
        {
            if (cmd.Connection != null)
            {
                cmd.Connection.Close();
                cmd.Connection.Dispose();
            }
            cmd.Dispose();
        }
    }
    catch { } //don't blow up
}

Затем я всегда создаю команды SQL и соединения в блоке try (но без переноса в блок using) и всегда имею блок finally как:

    finally
    {
        DisposeCommand(cmd);
    }

Объект соединения, являющийся свойством объекта команды, делает блок использования неудобным в этой ситуации - но этот шаблон выполняет работу, не загромождая ваш код.

...