SqlCommand.Dispose закрывает соединение?

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

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 (который вызывается при выходе из блока использования) закрыть базовый объект SqlConnection или нет?

Ответ 1

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

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

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

EDIT:

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

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();  

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

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

Ответ 2

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

Ответ 3

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

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);
    }

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