2008-10-07 3 views
11

У меня есть страница ASP.NET с множеством элементов управления, которые необходимо заполнить (например, выпадающие списки).DataReader или DataSet при перемещении нескольких наборов записей в ASP.NET

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

Я мог бы вернуть несколько таблиц в DataSet, или я мог бы вернуть DataReader и использовать «.NextResult», чтобы каждый набор результатов в пользовательский бизнес-класс.

Возможно, я увижу достаточно большое преимущество в производительности, используя подход DataReader, или я просто должен использовать подход DataSet?

Любые примеры того, как вы обычно справляетесь с этим, будут оценены.

ответ

1

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

Лично с несколькими выпадающими списками я обычно перебираю отдельные фрагменты данных, чтобы получить их, вместо того, чтобы хранить хранимую процедуру, которая возвращает 5 наборов результатов.

4

Всегда помещайте свои данные в классы, определенные для конкретного использования. Не пропускайте DataSet или DataReaders.

+2

Под «всегда» вы имеете в виду «иногда?». – 2008-10-07 21:04:21

+0

Не делайте этого! Не проходите мимо них! * вздрагивает * – wprl 2008-10-07 22:16:49

+3

От тяжелого заработанного опыта. НИКОГДА НИКОГДА НИКОГДА. Если вы не делаете очень проторенный прототип. Я живу с неиспользуемыми наборами данных, летающими повсюду. В начале они кажутся хорошей идеей (эй, это lighning development !!), но они становятся перетаскиванием, когда вы пытаетесь сохранить или построить/расширить его. Принимая 30 минут больше, записывая классы для данных, платит почти мгновенно (тестирование единицы?). – argatxa 2009-12-19 20:11:21

2

Если вы не заинтересованы в обновлении или удалении записей, извлеченных из базы данных, я бы предложил использовать DataReader. В основном DataSet внутренне использует несколько Datareaders, поэтому DataReader должен дать вам хорошее преимущество в производительности.

3

Сопоставьте DataReader с промежуточными объектами, а затем привяжите элементы управления с помощью этих объектов. В некоторых случаях можно использовать DataSets, но это мало и далеко, когда у вас есть веские причины «просто получать данные». Независимо от того, что вы делаете, не передавайте DataReader в свои элементы управления, чтобы связывать (не то, что вы сказали, что считаете это).

Моим личным предпочтением было бы использовать ORM, но если вы собираетесь рулонный доступ к данным, я думаю, вам следует предпочесть сопоставление DataReaders с объектами с использованием DataSets. Использование .NextResult как способ ограничить себя от попадания в базу данных несколько раз - это обоюдоострый меч, но так разумно выбирать. Вы обнаружите, что повторяете себя, если пытаетесь создать procs, которые всегда захватывают именно то, что вам нужно, используя только один вызов в базе данных. Если ваше приложение - всего несколько страниц, это, вероятно, хорошо, но все может быстро выйти из-под контроля. Лично я предпочел бы иметь один proc для типа объекта, а затем несколько раз ударять по базе данных (один раз для каждого типа объекта), чтобы максимизировать ремонтопригодность. Здесь ORM светит, потому что хороший будет генерировать Sql, который в большинстве случаев обеспечит вас именно тем, что вы хотите с помощью одного вызова.

2

Практически во всех ситуациях DataReader s are the best solution для чтения из базы данных. DataReader s - faster и требуют меньше памяти, чем DataTable s или DataSet s.

Кроме того, DataSet s часто может приводить к ситуациям, в которых модель OO составляет broken. Это не очень объектно ориентированная передача данных реляционных данных/схем вместо объектов, которые умеют манипулировать этими данными.

Таким образом, расширяемость, масштабируемость, модульность, и из соображений производительности, всегда используйте DataReader сек, если вы считаете себя настоящий программист ™;)

Проверьте ссылки на факты и дискуссии о двух в теории и практике.

0

Посмотрите на TableAdapters, которые доступны с .NET 2.0 и выше. То, что они делают, дает вам силу строго типизированного DataTable и позволяет сопоставить метод Fill с ним, который будет использовать DataReader для его загрузки. Ваш метод заполнения может быть существующими хранимыми процедурами, вашим собственным AdHoc SQL или даже позволить мастеру генерировать AdHod или хранимую процедуру для вас.

Вы можете найти это, запустив новый объект XSD DataSet в своем проекте. Для таблиц, которые используются не только для поиска, вы также можете сопоставить методы вставки/обновления/удаления с TableAdapter.

4

Если ваш сохраненный proc возвращает несколько наборов, используйте DataReader.NextResult для перехода к следующему фрагменту данных. Таким образом, вы можете получить все свои данные, загрузить их на свои объекты и как можно скорее закрыть читателя. Это будет самый быстрый способ получить ваши данные.

7
  1. Если у вас есть более чем 1000 запись, чтобы принести из базы данных.
  2. Если вы не очень заинтересованы в пользовательском хранении и пользовательского пейджинг «Для GridView»
  3. Если ваш сервер имеет напряжение памяти.
  4. Если нет проблем с подключением к вашей базе данных каждый раз, когда вызываемая страница .

Тогда я думаю, что лучше использовать DataReader.

еще

  1. Если у вас меньше, чем 1000 запись, чтобы принести из базы данных.
  2. Если вы заинтересованы хранения и пейджинг «Для GridView»
  3. Если ваш сервер не в памяти стресса.
  4. Если вы хотите подключиться к базе данных один раз и получить преимущества Кэширование.

Тогда я думаю, что лучше использовать DataSet.

Я хожу, что я прав.

2

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

В отношении должны ли вы когда-либо заморачиваться с несколькими результирующих наборов, мудрость в том, что вы не должны, но я могу представить себе разумный класс исключений из этого правила: (плотно), связанные результирующие-наборы , Вы, конечно же, не хотите добавлять запрос для возврата того же набора вариантов для раскрывающегося списка, который повторяется на сотнях или даже десятках страниц в вашем приложении, но несколько наборов, которые используются узко, могут быть разумно объединены. Например, в настоящее время я создаю страницу для отображения нескольких наборов «несоответствий» для партии данных ETL. Ни один из этих запросов, скорее всего, не будет использоваться в других местах, поэтому было бы удобно инкапсулировать их в виде простого «получить расхождения» sproc. С другой стороны, более высокая производительность при этом может быть незначительной по сравнению с обходной архитектурой с естественным однострочным однокомпонентным набором ваших ORM или ручным списком доступа к данным.

4

Увидев, что ответа еще нет, хотя уже есть хорошие ответы, я думал, что добавлю и два бита.

Я бы использовал DataReaders, так как они довольно быстро (если производительность - это ваша вещь или вам нужно столько, сколько вы можете получить). Большинство проектов, над которыми я работал, имеют миллионы записей в каждой из таблиц и производительности.

Некоторые люди сказали, что не рекомендуется отправлять DataReader через слои. Я лично не вижу в этом проблемы, поскольку «DbDataReader» не привязан (или не обязательно) к базе данных. То есть вы можете создать экземпляр DbDataReader без необходимости в базе данных.

Почему я это делаю по следующим причинам: Часто (в веб-приложении) вы генерируете либо Html, либо Xml, либо JSON, либо другое преобразование ваших данных. Итак, зачем переходить от DaraReader к некоторому объекту POCO только для его преобразования в XML или JSON и отправлять его по проводке. Для такого рода процессов обычно требуется 3 преобразования и загрузочная загрузка экземпляров объектов только для того, чтобы выбросить их почти мгновенно.

В некоторых ситуациях это нормально или не может помочь. В слое «Мои данные» обычно используются два метода для каждой хранимой процедуры, которые у меня есть в системе. Один возвращает DbDataReader, а другой возвращает DataSet/DataTable. Методы, возвращающие DataSet/DataTable, вызывают метод, возвращающий DbDataReader, а затем использует метод Load для DataTable или адаптера для заполнения набора данных. Иногда вам нужны DataSets, потому что вам, вероятно, придется каким-то образом перепрофилировать данные или вам нужно запустить другой запрос, и если у вас включен MARS, вы не сможете открыть DbDataReader и запустить другой запрос.

Теперь есть некоторые проблемы с использованием DbDataReader или DataSet/DataTable, и это, как правило, четкость кода, проверка времени компиляции и т. Д. Вы можете использовать классы-оболочки для своего datareader, и на самом деле вы можете использовать ваши DataReaders с IEnumerable с ними. Действительно крутая возможность. Таким образом, вы не только получаете сильную типизацию и читаемость кода, но и получаете IEnumerable!

Таким образом, класс может выглядеть следующим образом.

public sealed class BlogItemDrw : BaseDbDataReaderWrapper 
{ 
    public Int64 ItemId { get { return (Int64)DbDataReader[0]; } } 
    public Int64 MemberId { get { return (Int64)DbDataReader[1]; } } 
    public String ItemTitle { get { return (String)DbDataReader[2]; } } 
    public String ItemDesc { get { if (DbDataReader[3] != DBNull.Value) return (String)DbDataReader[3]; else return default(String); } } 
    public DateTime ItemPubdate { get { return (DateTime)DbDataReader[4]; } } 
    public Int32 ItemCommentCnt { get { return (Int32)DbDataReader[5]; } } 
    public Boolean ItemAllowComment { get { return (Boolean)DbDataReader[6]; } } 
    public BlogItemDrw() 
     :base() 
    { 
    } 

    public BlogItemDrw(DbDataReader dbDataReader) 
     :base(dbDataReader) 
    { 
    } 
} 

DataReader Wrapper

У меня есть сообщение в блоге (ссылка выше), который идет в гораздо более подробно, и я буду делать генератор исходного кода для них и другого кода DataAccess слоя.

Вы можете использовать ту же технику для DataTables (генератор кода создает код), поэтому вы можете рассматривать их как строго типизированный DataTable без накладных расходов на то, что VS.NET предоставляет из коробки.

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

Смежные вопросы