c # закрытие sqlconnection и sqldatareader или нет? - PullRequest
4 голосов
/ 08 декабря 2010

У меня есть этот кусок кода:

<CODE>
SqlConnection conn;
string strconString = System.Configuration.ConfigurationManager.ConnectionStrings["SQLCONN"].ToString();
conn = new SqlConnection(strconString);
string cmdstr = "select status from racpw where vtgid = " + vtgid;
SqlCommand cmdselect = new SqlCommand(cmdstr, conn);
conn.Open();
SqlDataReader dtr = cmdselect.ExecuteReader();
if (dtr.Read())
{
return;
}
else
{
...
}
dtr.Close();
conn.Close();
</code>

Теперь мой вопрос.При возврате автоматически закрывается ли мое соединение и dtr, или я должен использовать переменную bool и выполнять возврат после закрытия моих соединений?

Ответы [ 4 ]

9 голосов
/ 08 декабря 2010

Вы должны закрыть соединение перед возвратом. Лучший способ сделать это - ИСПОЛЬЗОВАТЬ блок, потому что SqlConnection реализует интерфейс IDisposable. В этом случае вам не нужно помнить о том, что вы должны закрыть соединение, даже если возникло исключение.

См. Пример ниже:

using (var conn = new SqlConnection(strconString))
{
    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;
    using (var cmdselect = new SqlCommand(cmdstr, conn))
    {
        conn.Open();
        using(var dtr = cmdselect.ExecuteReader())
        {
            if (dtr.Read())
            {
                return;
            }
            else
            {
                ...
            }
        }
    }
}
4 голосов
/ 08 декабря 2010

Вот как улучшить ваш код:

var connectionString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (var conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = 
            "select status from racpw where vtgid = @vtgid";

        cmd.Parameters.AddWithValue("@vtgid", vtgid);

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                ...
            }
        }
    }
}

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

3 голосов
/ 08 декабря 2010

Лучше всего использовать вместо этого блок using.Это принудительно вызовет Dispose, даже если вы вернетесь в середине метода:

string strconString = System.Configuration.ConfigurationManager
    .ConnectionStrings["SQLCONN"].ToString();

using (SqlConnection conn = new SqlConnection(strconString))
{
    string cmdstr = 
        "select status from racpw where vtgid = " + vtgid;

    using(SqlCommand cmdselect = new SqlCommand(cmdstr, conn))
    {
        conn.Open();
        using( SqlDataReader dtr = cmdselect.ExecuteReader())
        {
            if (dtr.Read())
            {
                return;
            }
            else
            {
                ...
            }
        }
    }
}

Это работает, потому что using на самом деле является блоком try/finally, и даже если вы вернетесь,Блок finally выполняется и запускается Dispose на ваших SqlCommand и SqlDataReader.

1 голос
/ 08 декабря 2010

Как уже отмечали другие, SqlConnection реализует IDisposable. IDisposable существует, так что вы можете контролировать, когда ресурсы будут освобождены. Если вы не вызываете Dispose самостоятельно, ваше соединение все равно будет автоматически закрыто, но вы не сможете контролировать, когда это может произойти (к вашему сведению, это произойдет, когда сборщик мусора соберет объект)

...