2

I have a memory leak, due to not closing the connection properly. This is due to using a global function to access the database (with different sql strings), but I pass back an sqldatareader. I cant close this in the method, nor the connection to the DB, as it closes access to the data! And it doesnt close properly from outside this method. :(

Is there Anyway way I can take the desired table, that the sqldatareader grants access to, offline. So that I can close all the connections, but still access the table.

Note, Different tables are returned so different fields exist. I dont want to have to duplicate code each time I try and connect.

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.
}

or maybe a valid working way of closing it all down outside the method (after I have accessed what I need)?

Yuval Itzchakov
  • 141,979
  • 28
  • 246
  • 306
IAmGroot
  • 13,538
  • 18
  • 80
  • 152
  • possible duplicate of [Return DataReader from DataLayer in Using statement](http://stackoverflow.com/questions/850065/return-datareader-from-datalayer-in-using-statement) – nawfal Feb 11 '13 at 18:04

4 Answers4

3

You could just return a DataTable instead of a SqlDataReader. This will fill the table with your data and you can close the connections before the method ends its execution.

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

This might be worth a read.

Connell
  • 13,275
  • 9
  • 56
  • 88
2

Don't return the reader, return a populated DataTable instead.

Neil Barnwell
  • 39,780
  • 28
  • 147
  • 218
2

Try the DataTable.Load Method method:

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;
}
Tim
  • 27,799
  • 8
  • 61
  • 74
1

You could consider using using something like a DataSet that provides off-line access to your data. Some examples here - http://msdn.microsoft.com/en-us/library/ms971499.aspx

or

This question provides a number of methods for taking the data out of a datareader and storing it in memory - How can I easily convert DataReader to List<T>?

Community
  • 1
  • 1
ipr101
  • 23,772
  • 7
  • 57
  • 61