Увидев, что ответа еще нет, хотя уже есть хорошие ответы, я думал, что добавлю и два бита.
Я бы использовал 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 предоставляет из коробки.
Имейте в виду, что существует только один экземпляр класса обертки. Поэтому вы не создаете сотни экземпляров класса, чтобы просто выбросить его.
Под «всегда» вы имеете в виду «иногда?». – 2008-10-07 21:04:21
Не делайте этого! Не проходите мимо них! * вздрагивает * – wprl 2008-10-07 22:16:49
От тяжелого заработанного опыта. НИКОГДА НИКОГДА НИКОГДА. Если вы не делаете очень проторенный прототип. Я живу с неиспользуемыми наборами данных, летающими повсюду. В начале они кажутся хорошей идеей (эй, это lighning development !!), но они становятся перетаскиванием, когда вы пытаетесь сохранить или построить/расширить его. Принимая 30 минут больше, записывая классы для данных, платит почти мгновенно (тестирование единицы?). – argatxa 2009-12-19 20:11:21