Как кто-то, кто не использовал ни технологии в реальных проектах, интересно, знает ли кто-нибудь, как эти два дополняют друг друга и насколько их функции перекрываются?
NHibernate vs LINQ to SQL
Ответ 1
LINQ to SQL заставляет использовать шаблон table-per-class. Преимущества использования этого шаблона состоят в том, что его быстро и просто реализовать, и требуется очень мало усилий для того, чтобы ваш домен работал на основе существующей структуры базы данных. Для простых приложений это вполне приемлемо (и часто даже предпочтительнее), но для более сложных приложений разработчики часто предлагают использовать доменный дизайн (что облегчает NHibernate).
Проблема с шаблоном table-per-class заключается в том, что ваша структура базы данных оказывает прямое влияние на дизайн вашего домена. Например, скажем, у вас есть таблица Customers со следующими столбцами для хранения информации о первичных адресах клиента:
- StreetAddress
- Город
- Государство
- Zip
Теперь скажем, вы хотите добавить столбцы для почтового адреса клиента, чтобы добавить в следующие столбцы таблицы Customers:
- MailingStreetAddress
- MailingCity
- MailingState
- MailingZip
Используя LINQ to SQL, объект Customer в вашем домене теперь будет иметь свойства для каждого из этих восьми столбцов. Но если вы следовали шаблону проектирования, управляемого доменом, вы, вероятно, создали класс Address, и у вашего класса Customer были бы два свойства Address, один для почтового адреса и один для их текущего адреса.
Это простой пример, но он демонстрирует, как шаблон table-per-class может привести к несколько вонючей области. В конце концов, это зависит от вас. Опять же, для простых приложений, которым просто нужны базовые функции CRUD (создание, чтение, обновление, удаление), LINQ to SQL идеален из-за простоты. Но лично мне нравится использовать NHibernate, потому что это облегчает более чистый домен.
Изменить: @lomaxx - Да, пример, который я использовал, был упрощенным и мог быть оптимизирован для работы с LINQ to SQL. Я хотел держать его как можно более простым, чтобы довести дело до конца. Дело остается в том, что существует несколько сценариев, в которых ваша структура базы данных определяет структуру вашего домена, будет плохой идеей или, по крайней мере, приведет к субоптимальному проектированию OO.
Ответ 2
Две точки, которые были пропущены до сих пор:
-
LINQ to SQL не работает с Oracle или любую базу данных, кроме SqlServer. Однако третьи стороны предлагают лучшую поддержку для Oracle, например. devArt dotConnect, DbLinq, Mindscape LightSpeed и ALinq. (У меня нет никакого личного опыта)
-
Linq to NHibernate позволяет использовать Linq с Nhiberate, поэтому он может удалить причину не использовать.
Кроме того, новый свободный интерфейс для Nhibernate, кажется, делает его менее болезненным для настройки отображения Nhibernates. (Удаление одной из болевых точек Ныберната)
Update
Linq to Nhiberate лучше в Nhiberate v3, который теперь находится в alpha. Похоже, что Nhiberate v3 может отправиться в конце этого года.
Работа с рамками Entity Frame с .net 4 также начинает выглядеть как реальный вариант.
Ответ 3
@Kevin: Я думаю, что проблема с примером, который вы представляете, заключается в том, что вы используете плохой дизайн базы данных. Я бы подумал, что вы создадите таблицу клиентов и таблицу адресов и нормализовали таблицы. Если вы это сделаете, вы можете использовать Linq To SQL для сценария, который вы предлагаете. У Скотта Гатри есть отличная серия сообщений об использовании Linq To SQL, которые я настоятельно рекомендую вам проверить.
Я не думаю, что вы могли бы сказать, что Linq и NHibernate дополняют друг друга, поскольку это подразумевает, что они могут использоваться вместе, и, хотя это возможно, вам гораздо лучше выбрать один и придерживаться его.
NHibernate позволяет вам гибко сопоставлять таблицы базы данных с объектами домена. Он также позволяет использовать HBL для запроса базы данных.
Linq to SQL также позволяет вам сопоставлять объекты домена с базой данных, однако он использует синтаксис запроса Linq для запроса базы данных
Основное отличие здесь в том, что синтаксис запроса Linq проверен компилятором во время компиляции, чтобы гарантировать, что ваши запросы действительны.
Некоторые вещи, о которых нужно знать в linq, это то, что он доступен только в .net 3.x и поддерживается только в VS2008. NHibernate доступен в версиях 2.0 и 3.x, а также VS2005.
Некоторые вещи, которые нужно знать в NHibernate, это то, что он не генерирует ваши объекты домена и не генерирует файлы сопоставления. Вам нужно сделать это вручную. Linq может
сделайте это автоматически для вас.
Ответ 4
Fluent NHibernate может генерировать ваши файлы сопоставления на основе простых соглашений. Нет XML-записи и строго типизировано.
Недавно я работал над проектом, где нам нужно было перейти от Linq To SQL к NHibernate по соображениям производительности. Особенно L2S способ материализации объектов кажется медленнее, чем NHibernate, но управление изменениями также довольно медленное. И может быть сложно отключить управление изменениями для определенных сценариев, где это не требуется.
Если вы собираетесь использовать ваши сущности, отключенные от DataContext - например, в сценариях WCF - у вас может быть много проблем с подключением их к DataContext для обновления изменений. У меня не было проблем с NHibernate.
То, что я пропущу из L2S, - это, в основном, генерация кода, поддерживающая отношения на обоих концах сущностей. Но я думаю, есть некоторые инструменты для NHibernate, чтобы сделать это там тоже...
Ответ 5
Можете ли вы пояснить, что вы подразумеваете под "LINQ"?
LINQ не является технологией доступа к данным, это просто функция языка, которая поддерживает запросы как встроенную конструкцию. Он может запрашивать любую объектную модель, которая поддерживает определенные интерфейсы (например, IQueryable).
Многие ссылаются на LINQ To SQL как LINQ, но это совсем не так. Microsoft только что выпустила LINQ To Entities с .NET 3.5 SP1. Кроме того, NHibernate имеет интерфейс LINQ, поэтому вы можете использовать LINQ и NHibernate для получения ваших данных.
Ответ 6
По LINQ, я предполагаю, что вы имеете в виду LINQ to SQL, потому что LINQ сам по себе не имеет связанной с ним базы данных "goings on". Это просто язык запросов, на котором загружается синтаксический сахар на лодке, чтобы он выглядел как SQL-ish.
В базовых базовых примерах NHibernate и LINQ to SQL, похоже, решают одну и ту же проблему. Как только вы получите пропуск, вы скоро поймете, что NHibernate поддерживает множество функций, которые позволяют создавать действительно богатые модели домена. Существует также проект LINQ to NHibernate, который позволяет использовать LINQ для запроса NHibernate во многом так же, как вы бы использовали LINQ to SQL.
Ответ 7
Сначала давайте разделим две разные вещи: Моделирование базы данных связано с данными, а объектное моделирование касается сущностей и отношений.
Преимущество Linq-to-SQL заключается в том, чтобы быстро генерировать классы из схемы базы данных, чтобы их можно было использовать в качестве активных объектов записи (см. определение шаблона активной записи).
Преимущество NHibernate заключается в том, чтобы обеспечить гибкость между вашим объектом и моделированием базы данных. База данных может быть смоделирована для наилучшего отражения ваших данных с учетом производительности, например. Хотя ваше моделирование объектов лучше всего отражает элементы бизнес-правила, используя такой подход, как Domain-Driven-Design. (см. комментарий Кевина Панга)
С устаревшими базами данных с плохими соглашениями о моделировании и/или именовании Linq-to-SQL будет отражать эти нежелательные структуры и имена для ваших классов. Однако NHibernate может скрыть этот беспорядок с помощью карт данных.
В проектах greenfield, где базы данных имеют хорошее именование и низкую сложность, Linq-to-SQL может быть хорошим выбором.
Однако вы можете использовать Fluent NHibernate с автосоединениями для этой же цели с отображением как соглашение. В этом случае вы не беспокоитесь о каких-либо картах данных с XML или С# и позвольте NHibernate генерировать схему базы данных из ваших объектов на основе соглашения, которое вы можете настроить.
С другой стороны, кривая обучения Linq-to-SQL меньше, чем NHibernate.
Ответ 8
Или вы можете использовать проект Castle ActiveRecords. Я использовал это в течение короткого времени, чтобы развернуть новый код для старого проекта. Он использует NHibernate и работает на активной схеме записи (удивительно, учитывая свое имя, которое я знаю). Я не пробовал, но я предполагаю, что, как только вы его используете, если вы почувствуете необходимость сразу перейти на поддержку NHibernate, это не будет слишком большим для этого для части или всего вашего проекта.
Ответ 9
Как вы писали "для человека, который не использовал ни одного из них", LINQ to SQL прост в использовании, поэтому любой может легко использовать его Он также поддерживает процедуры, которые помогают большую часть времени. Предположим, вы хотите получить данные из более чем одной таблицы, затем напишите процедуру и перетащите эту процедуру в конструктор, и она создаст все для вас, Предположим, что ваше имя процедуры - "CUSTOMER_ORDER_LINEITEM", которые извлекают запись из всех этих трех таблиц, а затем просто пишут
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
вы также можете использовать объект records в цикле foreach, который не поддерживается NHibernate