SqlDataAdapter vs SqlDataReader

В чем разница между использованием SqlDataAdapter vs SqlDataReader для получения данных из БД?

Я специально рассматриваю их "за" и "против", а также их скорость и производительность памяти.

Спасибо

Ответ 1

SqlDataReader:

  • Держит соединение открытым до тех пор, пока вы не закончите (не забудьте закрыть его!).
  • Как правило, может быть повторен только один раз
  • Не так полезно для обновления обратно в базу данных

С другой стороны, это:

  • Только одна запись в памяти за раз, а не весь набор результатов (это может быть огромным)
  • Примерно так быстро, как вы можете получить за одну итерацию
  • Позволяет начать обработку результатов раньше (как только появится первая запись)

SqlDataAdapter/DataSet

  • Позволяет закрыть соединение, как только оно завершит загрузку данных, и может даже автоматически закрыть его для вас
  • Все результаты доступны в памяти
  • Вы можете перебирать его столько раз, сколько вам нужно, или даже искать конкретную запись по индексу
  • Имеет несколько встроенных способностей для обновления обратно в базу данных

За счет:

  • Гораздо выше использование памяти
  • Вы ждете, пока все данные не будут загружены, прежде чем использовать какой-либо из них

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

Для получения дополнительной информации см. официальную документацию Microsoft.

Ответ 2

Ответ на это может быть довольно широким.

По сути, основное различие для меня, которое обычно влияет на мои решения, на которых следует использовать, - это то, что с помощью SQLDataReader вы "потоковой" передаете данные из базы данных. С помощью SQLDataAdapter вы извлекаете данные из базы данных в объект, который сам может быть запрошен дополнительно, а также выполнение операций CRUD.

Очевидно, что с потоком данных SQLDataReader МНОГО быстрее, но вы можете обрабатывать только одну запись за раз. С помощью SQLDataAdapter у вас есть полная коллекция совпадающих строк с вашим запросом из базы данных для работы с /pass через ваш код.

ПРЕДУПРЕЖДЕНИЕ: Если вы используете SQLDataReader, ВСЕГДА, ВСЕГДА, ВСЕГДА убедитесь, что вы написали правильный код, чтобы закрыть соединение, поскольку вы поддерживаете соединение открытым с помощью SQLDataReader. Если это не так, или правильная обработка ошибок, чтобы закрыть соединение в случае ошибки при обработке результатов, будет CRIPPLE ваше приложение с утечками соединения.

Простите мой VB, но это минимальный объем кода, который вы должны использовать при использовании SqlDataReader:

Using cn As New SqlConnection("..."), _
      cmd As New SqlCommand("...", cn)

    cn.Open()
    Using rdr As SqlDataReader = cmd.ExecuteReader()
        While rdr.Read()
            ''# ...
        End While
    End Using
End Using     

эквивалент С#:

using (var cn = new SqlConnection("..."))
using (var cmd = new SqlCommand("..."))
{
    cn.Open();
    using(var rdr = cmd.ExecuteReader())
    {
        while(rdr.Read())
        {
            //...
        }
    }
}

Ответ 3

A SqlDataAdapter обычно используется для заполнения DataSet или DataTable, и поэтому у вас будет доступ к данным после того, как ваше соединение будет закрыто (отключенный доступ).

SqlDataReader - это быстрый прямой и подключенный курсор, который, как правило, быстрее, чем заполнение DataSet/DataTable.

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

Если вам не нужно хранить свои данные в памяти, поэтому для получения всего материала, перейдите на SqlDataReader. Если вы хотите разобраться с вашими данными в отключенном режиме, выберите DataAdapter, чтобы заполнить DataSet или DataTable.

Ответ 4

Используйте SqlDataAdapter, когда вы хотите заполнить DataSet/DataTable в памяти из базы данных. Затем у вас есть гибкость, чтобы закрыть/удалить соединение, передать данные/установить в памяти. Затем вы можете манипулировать данными и сохранять их обратно в БД с помощью адаптера данных в сочетании с InsertCommand/UpdateCommand.

Использовать SqlDataReader при желании получить быстрый доступ к данным с низкой памятью без необходимости гибкости, например. передавая данные вокруг вашей бизнес-логики. Это более оптимально для быстрого использования памяти с большими объемами памяти с большими объемами данных, поскольку она не загружает все данные в память за один раз - с помощью подхода SqlDataAdapter, DataSet/DataTable будет заполнен всеми данными, поэтому, если там много строк и столбцов, для которых требуется много памяти.

Ответ 5

Функция Fill использует DataReader внутри. Если вы считаете, "Какой из них более эффективен?", То использование DataReader в узком цикле, который заполняет коллекцию запись за записью, вероятно, будет такой же нагрузкой в системе, как и использование DataAdapter.Fill.

(System.Data.dll, System.Data.Common.DbDataAdapter, FillInternal.)