C# Как перевести sqlDataReader в автономный режим?

У меня утечка памяти из-за неправильного закрытия соединения. Это связано с использованием глобальной функции для доступа к базе данных (с разными строками sql), но я возвращаю sqldatareader. Я не могу закрыть ни это в методе, ни подключение к БД, так как он закрывает доступ к данным! И он не закрывается должным образом снаружи этого метода. :(

Есть ли какой-нибудь способ получить нужную таблицу, к которой sqldatareader предоставляет доступ, в автономном режиме? Чтобы я мог закрыть все соединения, но по-прежнему получать доступ к таблице.

Примечание. Возвращаются разные таблицы, поэтому существуют разные поля. Я не хочу дублировать код каждый раз, когда пытаюсь подключиться.

private SqlDataReader OpenDataStream(String sql)
{
    SqlCommand sqlComm = new SqlCommand();
    sqlComm.Connection = new SqlConnection();
    sqlComm.Connection.ConnectionString = @"Myconnectionstring";
    sqlComm.CommandText = sql;
    sqlComm.Connection.Open();
    SqlDataReader data = null;
    data = sqlComm.ExecuteReader();

    return data;

    // Closing data here, or connection, results in returned object inaccessable.
}

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


person IAmGroot    schedule 27.10.2011    source источник
comment
возможный дубликат Return DataReader from DataLayer в операторе Using   -  person nawfal    schedule 11.02.2013


Ответы (4)


Попробуйте метод DataTable.Load:

private DataTable OpenDataStream(String sql)
{

    DataTable dt = new DataTable();

    SqlCommand sqlComm = new SqlCommand();
    sqlComm.Connection = new SqlConnection();
    sqlComm.Connection.ConnectionString = @"Myconnectionstring";
    sqlComm.CommandText = sql;
    sqlComm.Connection.Open();
    SqlDataReader data = null;
    data = sqlComm.ExecuteReader();

    dt.Load(data);

    data.Close();

    return dt;
}
person Tim    schedule 27.10.2011

Вы можете просто вернуть DataTable вместо SqlDataReader. Это заполнит таблицу вашими данными, и вы сможете закрыть соединения до того, как метод завершит свое выполнение.

private DataTable GetDataTable(String sql)
{
    SqlDataAdapter da = new SqlDataAdapter(sql, connection);
    DataSet ds = new DataSet();
    da.Fill(ds);
    return ds.Tables[0];
}

Это стоит прочитать.

person Connell    schedule 27.10.2011

Не возвращайте считыватель, вместо этого возвращайте заполненный DataTable.

person Neil Barnwell    schedule 27.10.2011

Вы можете рассмотреть возможность использования чего-то вроде DataSet, который обеспечивает автономный доступ к вашим данным. Несколько примеров здесь — http://msdn.microsoft.com/en-us/library/ms971499.aspx

or

Этот вопрос предоставляет ряд методов для извлечения данных из устройства чтения данных и сохранения их в памяти - to-listt">Как легко преобразовать DataReader в List‹T›?

person ipr101    schedule 27.10.2011