Проблемы с SqlDataReader - PullRequest
       37

Проблемы с SqlDataReader

0 голосов
/ 16 февраля 2011

У меня проблема при хранении данных в SqlDataReader.Когда я передаю переменную sdr, в точке, где connection.close (), переменная sdr становится пустой.Почему?

   string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;

   SqlDataReader sdr = null;

    using (SqlConnection connection = new SqlConnection(strConnection))
    {
        connection.Open();
        using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
        {


            cmd.CommandType = System.Data.CommandType.StoredProcedure;

            sdr = cmd.ExecuteReader();


        }
        connection.Close();
    }

    return (sdr);

Ответы [ 2 ]

3 голосов
/ 16 февраля 2011

Вам нужно открытое и активное соединение при переборе DataReader. Если вы закроете его перед возвратом устройства чтения данных, оно не будет работать. Что я обычно делаю, чтобы обойти это, это превращаю DataReader в IEnumerable, вот так:

public IEnumerable<IDataRecord> GetProductsFromDB()
{
    string strConnection = ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString;

    using (SqlConnection connection = new SqlConnection(strConnection))
    using (SqlCommand cmd = new SqlCommand("GetProducts", connection))
    {
        cmd.CommandType = System.Data.CommandType.StoredProcedure;

        connection.Open();
        using (var sdr = cmd.ExecuteReader())
        {
            while (sdr.Read())
            {
                yield return sdr;
            }
        }    
    }
}

Обратите внимание, что я также немного изменил порядок: подождите как можно дольше, чтобы открыть соединение, и поместите соединение и создание команды рядом с каждым, чтобы избежать такого большого количества вложений.

Этот шаблон открывает совершенно новый мир для того, как вы пишете свой код доступа к данным, потому что теперь внезапно ваши необработанные запросы sql и вызовы хранимых процедур работают с операторами linq-to-objects. Вы можете сделать немного круто, как это:

foreach (var product in GetProductsFromDB()
           .Select(i => CreateProductFromDataRow(i))
           .Where(p => p.IsOnSale()) )
{
    // do something with products that are on sale
}
3 голосов
/ 16 февраля 2011

Вам нужно перебирать ридер в цикле при вызове Read:

while(sdr.Read())
{
   var someValue = sdr["SomeValue"]; //Where SomeValue is the column name you're expecting from the DB
}

Все, что делает ExecuteReader, это возвращает вам объект DataReader, однако вы должны пройти через каждую возвращенную строкуи вытащить ценности из этого.Если вы хотите получить все это за один раз, вы можете использовать SqlDataAdapter:

var adapter = new SqlDataAdapter(command);
var table = new DataTable();
adapter.Fill(table);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...