Соединение с SQL не закрывается после вызова БД в ASP.NET - PullRequest
0 голосов
/ 04 июня 2009

У меня есть универсальный метод для вызова хранимой процедуры в ASP.NET:

public SqlDataReader ExecuteStoredProc(string sprocName, SqlParameter[] SqlP)
        {
            SqlDataReader iReader;
            SqlCommand sql = new SqlCommand();

            sql.CommandText = sprocName;
            sql.CommandType = CommandType.StoredProcedure;
            sql.Connection = ConnStr;
            if (SqlP != null)
            {
                foreach (SqlParameter p in SqlP)
                {
                    sql.Parameters.Add(p);
                }

            }
            sql.Connection.Open();
            iReader = sql.ExecuteReader(CommandBehavior.CloseConnection);
            sql.Dispose();

            return iReader;
        }

Несмотря на то, что я вызываю CommandBehavior.CloseConnection, соединение не закрывается. Я могу получить данные в порядке при первом запросе страницы. При перезагрузке я получаю следующую ошибку:

Соединение не было закрыто. текущее состояние соединения открыто. Описание: необработанное исключение произошло во время исполнения текущий веб-запрос. Пожалуйста, просмотрите трассировка стека для получения дополнительной информации о ошибка и откуда она возникла код.

Сведения об исключении: System.InvalidOperationException: соединение не было закрыто. текущее состояние соединения открыто.

Ошибка источника:

Строка 35: Строка 36:} Строка 37: sql.Connection.Open (); Строка 38: iReader = sql.ExecuteReader (CommandBehavior.CloseConnection); Строка 39: sql.Dispose ();

Наконец, если я поставлю sql.Connection.Close (); перед sql.Dispose (); Я получаю сообщение об ошибке, что iReader не читается, потому что он уже закрыт.

Очевидно, что я неправильно закрываю соединение, может кто-то направить меня в правильном направлении?

Ответы [ 4 ]

4 голосов
/ 04 июня 2009

Когда вы возвращаете DataReader, базовое соединение должно оставаться открытым. Ответственность за правильную очистку ресурсов лежит на потребителе.

public SqlDataReader ExecuteStoredProc(string sprocName, SqlParameter[] SqlP)
{
    SqlCommand sql = new SqlCommand();

    sql.CommandText = sprocName;
    sql.CommandType = CommandType.StoredProcedure;
    sql.Connection = ConnStr;
    if (SqlP != null)
    {
        foreach (SqlParameter p in SqlP)
        {
            sql.Parameters.Add(p);
        }

    }
    sql.Connection.Open();
    return sql.ExecuteReader(CommandBehavior.CloseConnection);          
}

public void ConsumingMethod()
{
    using(SqlDataReader reader = ExecuteStoredProc("MyProc", params))
    {
        while(reader.Read())
        {
            //work with your reader
        }
    }
}
1 голос
/ 04 июня 2009

Я бы посоветовал обернуть соединение SQL с помощью оператора using, и это решит большинство проблем с подключением SQL.

using (var conn = new SqlConnection("..."))
{
    conn.Open();
    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandText = "...";
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // ...
            }
        }
    }

}

0 голосов
/ 04 июня 2009

Это мой предпочтительный способ обработки IDataReader. Пусть вызывающая сторона создает экземпляр SqlConnection и переходит к методам.

Создание экземпляра SqlConnection обходится дорого. И в итоге код вызовет один и тот же метод ExecuteStoredProc несколько раз в разных ситуациях.

Таким образом, я реорганизую метод ExecuteStoredProc, добавив экземпляр SqlConnection как часть параметра.

using (SqlConnection conn = new SqlConnection())
{
    conn.ConnectionString = // Connection String;
    conn.Open();

    using (IDataReader reader = foo.ExecuteStoredProc(conn, sprocName, SqlP))
    {
        // Process IDataReader
    }
}
0 голосов
/ 04 июня 2009

Идея состоит в том, чтобы сделать Connection.Close (); после того, как вы закончили работу с SqlReader, поэтому вместо того, чтобы помещать инструкцию close () перед командой SqlReader.Dispose (), вы должны поместить ее ниже.

...