Статьи

DataSet Vs. DataReader Статья

Мне нравится выполнять как можно меньше работы, когда я пишу код, поэтому мне нравился DataSet. Он может быть заполнен и готов к работе всего за 3 строки кода, а затем итерирован с использованием простого и удобного цикла foreach (это даже проще, если вы используете типизированные наборы данных!). Это хорошая коллекция для работы. Но часто производительность требуется за счет элегантности — особенно для критичного к производительности веб-приложения.

DataSet фактически использует DataReader для заполнения себя. DataReader — это простой метод среднего доступа, который возвращает результаты, как только они становятся доступными, вместо того, чтобы ждать, пока весь запрос будет заполнен в DataSet. Это может значительно повысить производительность вашего приложения и, как только вы привыкнете к методологии, само по себе может быть довольно элегантным.

Преимущества DataReader в действии

Чтобы подчеркнуть преимущества использования DataReader по сравнению с DataSet, вот пример использования DataSet. Следующее заполняет DataSet результатами таблицы и выводит первое поле в каждой строке:

SqlConnection conn = new SqlConnection(connectionString);  SqlDataAdapter a = new SqlDataAdapter  ("select * from mytable;",conn);  DataSet s = new DataSet();  a.Fill(s);  foreach (DataRow dr in s.Tables[0].Rows)  {  Console.WriteLine(dr[0].ToString());  } 

Как видите, мы фактически не запускаем фактическую проверку данных (цикл foreach), пока весь DataSet не будет заполнен. Могут быть случаи, когда мы можем не использовать все наши результаты, или мы можем выполнить другой код во время проверки (прогресс выполнения — простой пример). Используя DataSet, это может произойти только после того, как полные результаты будут получены и переданы в различные коллекции внутри DataSet.

Напротив, вот код, который достигает тех же результатов, используя DataReader вместо DataSet:

   SqlConnection conn = new SqlConnection(connectionString);  SqlCommand comm = new SqlCommand("select * from mytable", conn);  comm.Connection.Open();  SqlDataReader r =      comm.ExecuteReader(CommandBehavior.CloseConnection);  while(r.Read())  {    Console.WriteLine(r.GetString(0));  }  r.Close();  conn.Close();   

Здесь проверка выполняется, как только доступны данные, с помощью цикла while, где r.Read() возвращает false, если больше результатов не найдено. Поэтому мы можем не только проверять ход, но и DataReader сохраняет на клиенте только один результат за раз. Это приводит к значительному сокращению использования памяти и системных ресурсов по сравнению с DataSet, где хранится весь запрос.

Когда только DataSet будет достаточно

Теперь бывают случаи, когда достаточно только DataSet. Часто вам нужно сериализовать результаты или передать результаты запроса на следующий уровень вашего приложения. В этих случаях требуется коллекция, и DataSet предоставляет хорошо поддерживаемый механизм для этого. Например, вы можете быстро сериализовать DataSet в XML, вызвав метод WriteXML, или передать DataSet в метод SOAP. Несмотря на то, что вы можете создавать свои собственные коллекции для хранения результатов со всеми этими встроенными, оптимизированными функциями под рукой, DataSet по-прежнему является мощным типом, о котором следует помнить.

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