Доморощенные ORM против DataTables? - PullRequest
7 голосов
/ 07 ноября 2008

Это упрощение проблемы (есть много способов сделать что-то), но среди приложений, которым нужно общаться с базой данных, я обычно видел один из двух шаблонов:

  1. Object-Relational Mapping (ORM), где (как правило) каждая таблица в базе данных имеет соответствующий класс «упаковщик строк» ​​с открытыми свойствами, которые соответствуют столбцам в таблице. Иногда эти классы также автоматически извлекают связанную информацию, так что вместо этого столбцы внешнего ключа могут быть представлены и отображены как связанные данные (а не только значения PK).
  2. DataTables (и / или DataSets), где данные извлекаются с сервера в виде DataTable и обрабатываются в этой форме (даже в пользовательском интерфейсе).

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

Person bob = new Person();
bob.FirstName = "Bob";
collectionPeople.Add(bob);

тогда как при использовании DataTable ваш код будет выглядеть примерно так:

DataRow newrow = datatablePeople.NewRow();
newrow["FirstName"] = "Bob";
datatablePeople.Rows.Add(newrow);

В этом случае подход ORM выигрывает от проверки во время компиляции, а подход DataTable - нет. С другой стороны, DataTable (и DataSet) - это уже написанные структуры данных, которые отлично справляются с непосредственным представлением реляционных данных, поэтому код, использующий их, обычно может быть реализован быстрее. Кроме того, код, который использует DataTables, может быть легко понят и изменен другими; Домашние (и часто COTS) системы ORM часто предоставляют дополнительный доступ к базе данных «под капотом» для заполнения внешних ключей и т. д., что может создавать проблемы для незнающих.

Так какой подход вы обычно предпочитаете и почему?

Ответы [ 8 ]

8 голосов
/ 07 ноября 2008

Datatable, безусловно, будет концептуально более простым в работе с данными. И это лишено иногда неестественных идиом, которые вы найдете в ORM. (запрос записи в локальную память перед ее обновлением; объединения - это указатели; само значение ключа является указателем, следовательно, добавление записи требует загрузки родительской записи)

Большие преимущества для ORM - это ...

1) он пишет sql для вас, так что вам действительно не нужно писать какой-либо sql для выполнения базового crud. Конечно, написание более сложных утверждений должно быть сделано на менее мощном подъязыке (т.е. hql)

2) Другим большим преимуществом ORM является то, что когда вы возвращаете результаты, он отображает их в объекты-значения, без написания набора кода для сопоставления значений и обработки преобразования типов.

Если у вас сильные навыки sql, но вы хотите получить преимущество 2, я бы выбрал ibatis

7 голосов
/ 07 ноября 2008

Я предпочитаю способ DataTables, потому что я стар, устал и скептически отношусь к модам, таким как Subsonic и Linq.

Кроме того, когда вы работаете с ORM, вы обычно сводите к минимуму то, что делаете в SQL. Вы не вкладываете много логики в SQL и не объединяете несколько операторов SQL для выполнения нескольких операций за одну поездку в базу данных. Поэтому вы склонны чаще обращаться к базе данных, и это сильно сказывается на производительности.

Используя наборы данных, я могу сделать что-то вроде:

выберите col1, col2 ... из таблицы1
выберите col1, col2 ... из таблицы2
выберите col1, col2 ... из таблицы3

и затем совершите ОДНУ поездку в базу данных, чтобы получить все три набора данных, используя таблицы [0], таблицы [1], таблицы [2] для ссылки на них. Это очень сильно влияет на производительность.

Когда-нибудь, возможно, взаимодействие с базой данных будет настолько быстрым, что не будет смысла в пакетировании SQL, но этот день еще не наступил. Когда это произойдет, я переключусь на ORM, но до тех пор я хочу, чтобы мой код был немного уродливым в обмен на производительность. Пользователям неинтересно пользоваться медлительным приложением.

Наконец, мне нравится SQL. Я хорошо разбираюсь в SQL. Действительно хорошо. Я не хочу тратить свое время на выяснение того, как заставить Linq генерировать SQL, который я хочу. Это снизит производительность MY .

4 голосов
/ 30 ноября 2008

В наборах данных .Net со строгой типизацией есть преимущества, которые вы приписываете ORM - значение строгой типизации в IDE и Intellisense,

TableAdapters, созданный в Visual Studio, напишет весь ваш CRUD SQL для вас. Вы помещаете свою бизнес-логику в C # (или другой язык), а не в SQL.

Я думаю, что модель несвязанных данных, предлагаемая наборами данных, на практике оказывается более эффективной, чем типичный SQL с ручным кодированием. Это приводит к небрежному взаимодействию с БД, когда вы получаете все связанные данные таблицы в одном запросе. И он имеет очень хорошую поддержку для оптимистической блокировки (предоставляя исключения DBConcurrency). Набор данных также отслеживает вставки, изменения и удаления ваших данных, поэтому вам не нужно это делать.

Наборы данных со строгой типизацией также предлагают прямую навигацию к связанным данным таблицы.

Хорошая ссылка на DataSets -

Программирование Microsoft® ADO.NET 2.0 Базовая ссылка Дэвида Сцеппы

Издатель: Microsoft Press Pub Дата: 17 мая 2006 г. Печать ISBN-10: 0-7356-2206-X Печать ISBN-13: 978-0-7356-2206-7 Страницы: 800

+ * Том 1017 *

4 голосов
/ 07 ноября 2008

Вы можете объединить оба упомянутых подхода, используя строго типизированные наборы данных .

Можно добавить их в проект Visual Studio через диалоговое окно «Добавить новый элемент» «Шаблон набора данных», а затем использовать визуальный конструктор наборов данных (он редактирует XSD-файл за кулисами).

Есть еще одна статья по теме.

3 голосов
/ 07 ноября 2008

Я бы посмотрел на преимущества объектов данных по сравнению с DataTables (причудливая библиотека ORM на самом деле не нужна, хотя они могут быть хорошими):

  • Концептуально чисто. Вы вынуждены применять концепции ОО к вашим данным. Проще понять, что это «Человек», а не «Человек, которого я хочу, где-то в этой таблице».
  • Обеспечивает разделение интересов. Соблазнительно привязать данные контекста пользовательского интерфейса к DataTable - для одного пользовательского интерфейса я получаю Person с основным адресом в той же записи, для другого я получаю Person с кредитной информацией в той же записи. Когда я работаю с моделью, я хочу, чтобы эта модель была согласованной везде, где я ее потребляю.
  • Преобразование данных только один раз. В приложениях DataTable, которые я видел, много всего разбросано по всему:

    if (row ["col"] == DBNull.Value || string.IsNullOrEmpty (row ["col"] как строка)) ...

    Я бы предпочел проверить это условие один раз при заполнении объекта данных, чем проверять его везде, где используется DataTable.

  • Легче для модульного тестирования. Если вы ссылаетесь на поле в несуществующем объекте данных, вы получаете ошибку во время компиляции. Если вы ссылаетесь на поле в DataTable, которое не существует, вы получаете ошибку во время выполнения.

Я верю, что ORM может сделать вас ленивым. Например, нет абсолютно никакой причины заполнять набор связанных объектов данных из отдельных запросов в объектах, если эти объекты всегда используются вместе. Вместо этого напишите большой и эффективный запрос, который собирает все необходимые данные и затем строит граф объекта данных. Тем не менее, если вы будете помнить о его ограничениях, это сэкономит много работы.

Related: Как убедить моих коллег не использовать наборы данных для развития предприятия (.NET 2.0 +) .

2 голосов
/ 21 июня 2010

Раньше я использовал DataSets в первые дни .NET, затем начал использовать типизированные DataSets, со временем обнаружил, что объем памяти, оставляемый DataSets, очень высок, и не имело смысла использовать неуправляемые объекты для любых простых задач.
Поэтому пришли к выводу, что DTO / POCO - лучший выбор, и начали использовать NHibernate и iBatis.
Мои средние (или ниже среднего) разработчики находили их сложными и сложными в использовании (без каламбура).
Поэтому я сделал доморощенный ORM XmlDataMapper , который был намного легче используйте, что сложные ORM там.

Для интеграции XmlDataMapper все, что вам нужно сделать, - это 4 маленьких шага

  1. Создание бизнес-объекта / DTO для таблиц
  2. Создайте файл XML с информацией о сопоставлении между таблицей и DTO.
  3. Укажите файл DTO и xml в конфигурации.
  4. Просто вызовите DTOConverter.Convert (dataReader) и другие подобные методы для преобразования вашей записи базы данных в DTO / Business Entity
0 голосов
/ 07 ноября 2008

Я считаю, что могу разрабатывать меньше кода и тестировать свой код лучше, используя ORM, чем DataSets / DataTables. В настоящее время я использую LINQ-to-SQL и оборачиваю тонкий слой вокруг сгенерированного дизайнером кода через частичные классы в качестве моего ORM. Тонкий слой в основном позволяет мне добавлять некоторые разрешения на основе ролей и повышает тестируемость кода за счет рефакторинга интерфейсов и использования внедрения зависимостей для указания контекста данных (таким образом я могу смоделировать его для других тестов).

Я сделал и то и другое - написал свой собственный ORM для DS / DT, строго типизированного DS / DT и т. Д., Перешел на LINQ и не собираюсь возвращаться. В конечном итоге я могу перейти на что-то вроде NHibernate, Entity Framework или чего-то еще, но сейчас мое решение LINQ предлагает почти все, что мне нужно, и намного проще, чем мои старые решения.

0 голосов
/ 07 ноября 2008

Раньше я просто использовал устройство чтения данных для чтения полей в моем объекте, используя GetString, GetInt и т. Д., Но теперь я перешел к гораздо более понятному и тестируемому подходу, использующему шлюз для возврата данных из запроса. затем передается в класс Service, который анализирует таблицу на объекте.

Мне никогда не нравились инструменты ORM, они всегда были громоздкими и сложными в обслуживании, но у меня еще не было возможности поиграть с LINQ, поэтому мое мнение может измениться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...