NHibernate vs LINQ в SQL


117

Як того, хто не використовував жодної технології в реальних проектах, мені цікаво, чи хтось знає, як ці двоє доповнюють один одного і наскільки їх функціональні функції перетинаються?

Відповіді:


113

LINQ в SQL змушує використовувати шаблон таблиці за класом. Переваги використання цього шаблону полягають у тому, що його швидко та просто реалізувати, і для того, щоб ваш домен працював на основі існуючої структури бази даних, потрібно дуже мало зусиль. Для простих застосувань це цілком прийнятно (а часто навіть краще), але для більш складних застосувань розробники часто пропонують використовувати замість цього шаблон дизайну, керований доменом (що полегшує NHibernate).

Проблема з шаблоном таблиці на клас полягає в тому, що структура вашої бази даних має прямий вплив на дизайн вашого домену. Наприклад, скажімо, у вас є таблиця "Клієнти" із наступними стовпцями для зберігання основної інформації про клієнта:

  • Адреса вулиці
  • Місто
  • Держава
  • Zip

Скажімо, ви хочете додати стовпці для поштової адреси клієнта, щоб ви додали в наступні стовпці до таблиці Клієнти:

  • Адреса MailingStreetAddress
  • MailingCity
  • MailingState
  • MailingZip

Використовуючи LINQ для SQL, об’єкт Клієнта у вашому домені тепер матиме властивості для кожного з цих восьми стовпців. Але якби ви дотримувались схеми дизайну, керованої доменом, ви, ймовірно, створили клас адреси та мали б ваш клас Клієнта два властивості адреси, одну для поштової адреси та одну для їх поточної адреси.

Це простий приклад, але він демонструє, як модель таблиці за класом може призвести до дещо смердючої області. Зрештою, це залежить від вас. Знову ж таки, для простих додатків, які просто потребують базової функціональності CRUD (створювати, читати, оновлювати, видаляти), LINQ до SQL ідеально підходить через простоту. Але особисто мені подобається використовувати NHibernate, оскільки це сприяє більш чистому домену.

Редагувати: @lomaxx - Так, я використав приклад спрощений і міг бути оптимізований для роботи з LINQ в SQL. Я хотів, щоб це було максимально базовим, щоб загнати додому пункт. Справа, однак, існує декілька сценаріїв, коли структура вашої бази даних визначає вашу структуру домену було б поганою ідеєю або, принаймні, призводить до неоптимального дизайну ОО.


4
Ви можете кодувати реалізацію вашого сховища за допомогою Linq To SQL, це дуже зручно.
Ніколя Доріє

1
Я думаю, що це не ActiveRecord, навіть зіставлені класи містять частину логіки інфраструктури. Шаблон ActiveRecord буде, якщо ви можете мати Customer.Save (). L2S реалізує схему Unit of Work з класом DataContext, як сесія в nHibernate, але NH має реальний підхід POCO.
Хрвойе Худо

1
@kevin "LINQ в SQL використовує активну схему запису" Це неправильно. Це як би сказати, що ADO.NET використовує активний запис або NHibernate використовує активний запис. Всі вони є технологіями доступу до даних і не застосовують конкретного шаблону доступу до даних. Мені особисто подобається використовувати linq-to-sql з шаблоном сховища. Ви впевнені, що linq-to-sql не підтримує складні відображення, як це робить NHibernate.
liammclennan

1
Що про те, щоб замість цього нормалізувати вашу базу даних і дозволити генерувати свій DAL інструментами, наприклад SQLMetal?
Олексій

3
@CoffeeAddict Коли невідповідність імпедансу занадто велика, тоді ваша програма занадто складна для використання LINQ для SQL, imo. Причина, що мій приклад смердюча, полягає в тому, що використання LINQ в SQL призведе до 8 властивостей на відміну від 2 і обмежує вашу здатність виконувати такі дії, як функції реалізації, які беруть у клас адреси або реалізують підпрограми для класу Address, який ви могли б зробіть, якщо ви використовували NHibernate.
Кевін Панг

26

Два моменти, які до цього часу були пропущені:

  • LINQ в SQL не працює з Oracle або будь-якою базою даних, крім SqlServer. Однак треті сторони пропонують кращу підтримку Oracle, наприклад , dotConnect , DbLinq , Mindscape, LightSpeed і ALinq . (Я не маю жодного особистого досвіду з цим)

  • Linq to NHibernate дозволяє вам використовувати Linq з Nhiberate, тому це може усунути причину не використовувати.

Крім того, новий плавний інтерфейс до Nhibernate, здається, робить менш болісним налаштовувати відображення Nhibernate. (Видалення однієї з больових точок Nhibernate)


Оновлення

Linq to Nhiberate краще в Nhiberate v3, який зараз знаходиться в альфа . Схоже, Nhiberate v3 може доставитись наприкінці цього року.

Робота Entity Frame від .net 4 також починає виглядати як реальна опція.


2
Лінк до NHibernate ще на дуже ранній стадії. Це не повна реалізація, і, мабуть, зовсім не готова до використання у виробництві.
liammclennan

Новий випуск LinqConnect 2.0 пропонує зручності для зручності, такі як підтримка успадкування таблиці за типом, підтримка PLINQ та функція пакетного оновлення. ORM Designer (Devart Entity Developer) тепер має функцію підтримки першої моделі та синхронізацію карти. Детальніше: devart.com/news/2010/dotconnects600.html
Devart

23

@Kevin: Я думаю, що проблема з прикладом, який ви представляєте, полягає в тому, що ви використовуєте поганий дизайн бази даних. Я б подумав, що ви створите таблицю клієнтів та таблицю адрес і нормалізуєте таблиці. Якщо ви це зробите, ви можете безперечно використовувати Linq To SQL для запропонованого сценарію. У Скотта Гатрі є велика серія публікацій щодо використання Linq To SQL, яку я настійно пропоную вам перевірити.

Я не думаю, що ви можете сказати, що Linq та NHibernate доповнюють один одного, оскільки це означатиме, що вони можуть використовуватися разом, і, хоча це можливо, вам набагато краще вибрати один і дотримуватися його.

NHibernate дозволяє картувати таблиці вашої бази даних до об'єктів вашого домену дуже гнучко. Це також дозволяє використовувати HBL для запиту до бази даних.

Linq до SQL також дозволяє вам відображати об’єкти домену до бази даних, однак він використовує синтаксис запитів Linq для запиту до бази даних

Основна відмінність тут полягає в тому, що синтаксис запитів Linq перевіряється під час компіляції компілятором, щоб переконатися, що ваші запити є дійсними.

Деякі речі, які слід пам’ятати про linq, це те, що вона доступна лише у .net 3.x та підтримується лише у VS2008. NHibernate доступний у 2.0 та 3.x, а також у VS2005.

Деякі речі, які слід пам’ятати про NHibernate, це те, що він не генерує об’єкти вашого домену, а також не генерує файли відображення. Це потрібно зробити вручну. Linq може
зробити це автоматично для вас.


15
Що робити, якщо ви пишете код проти застарілої структури бази даних, яку ви не можете змінити, оскільки вона підтримує інші програми. Ви хочете, щоб ваша доменна модель успадкувала поганий дизайн бази даних, чи ви хочете створити багату модель домену, яка може змінюватись незалежно від структури бази даних?
Ларрі Фолкрод

7

Fluent NHibernate може генерувати ваші картографічні файли на основі простих конвенцій. Немає XML-написання та сильно набрано.

Нещодавно я працював над проектом, де нам потрібно було з міркувань продуктивності перейти з Linq на SQL на NHibernate. Особливо спосіб L2S матеріалізації об'єктів здається повільнішим, ніж дефіт NHibernate, і управління змінами теж досить повільне. І може бути важко вимкнути управління змінами для конкретних сценаріїв, де це не потрібно.

Якщо ви збираєтесь використовувати ваші особи, відключені від DataContext - наприклад, у сценаріях WCF - у вас можуть виникнути проблеми з підключенням їх до DataContext для оновлення змін. У мене з цим не було проблем з NHibernate.

Що я пропущу з L2S - це здебільшого генерація коду, яка постійно оновлює відносини на обох кінцях об'єктів. Але я думаю, що є кілька інструментів для NHibernate, щоб зробити це і там ...


2
Про всяк випадок, якщо інші прочитають вашу публікацію і теж думають про перехід корабля - .ObjectTrackingEnabled = falseна ваш рахунок DataContextвирішиться проблема відстеження змін. Поки ви купуєте схему одиничної роботи і не хочете робити DDD, Linq-до-SQL дійсно забезпечує.
mattmc3

" нам потрібно було перейти з Linq на SQL на NHibernate з міркувань продуктивності " - Користуючись [Fluent, не менш] NHibernate протягом декількох років, я відчуваю вас. Я думаю, що ми здебільшого обдурили і закінчили писати рідний SQL для реальних балів тиску на продуктивність. Було б цікаво почути оновлення (через шість років ...) про те, як пройшла ваша міграція та чи варта вона.
ruffin

5

Чи можете ви уточнити, що ви маєте на увазі під "LINQ"?

LINQ - це не технологія доступу до даних, це лише мовна функція, яка підтримує запити як нативну конструкцію. Він може запитувати будь-яку об'єктну модель, яка підтримує конкретні інтерфейси (наприклад, IQueryable).

Багато людей відносять LINQ до SQL як LINQ, але це зовсім не правильно. Щойно Microsoft випустила LINQ To Entities з .NET 3.5 SP1. Крім того, NHibernate має інтерфейс LINQ, тому ви можете використовувати LINQ та NHibernate для отримання своїх даних.


2

Під LINQ я припускаю, що ви маєте на увазі LINQ для SQL, оскільки LINQ сам по собі не має пов'язаних з ним баз даних. Це просто мова запиту, яка містить човен синтаксичного цукру, щоб він виглядав SQL-ish.

У самих основних базових прикладах, схоже, NHibernate та LINQ для SQL вирішують одну і ту ж проблему. Як тільки ви пройдете, ви незабаром зрозумієте, що NHibernate має підтримку безлічі функцій, які дозволяють створювати справді багаті моделі доменів. Існує також проект LINQ to NHibernate, який дозволяє використовувати LINQ для запиту NHibernate приблизно так само, як і LINQ для SQL.


1

Спочатку давайте розділимо дві різні речі: Моделювання баз даних стосується даних, а об'єктне моделювання стосується сутностей та відносин.

Перевага Linq-SQL полягає в швидкому генеруванні класів із схеми бази даних, щоб їх можна було використовувати як активні об'єкти запису (див. Визначення схеми дизайну активних записів).

Перевага NHibernate полягає в тому, щоб дозволити гнучкість між моделюванням об'єктів та моделюванням баз даних. База даних може бути змодельована так, щоб найкраще відображати ваші дані, наприклад, враховуючи ефективність роботи. У той час як ваше моделювання об'єктів найкраще відображатиме елементи бізнес-правила, використовуючи такий підхід, як «Управління доменом». (див. коментар Кевіна Панга)

З застарілими базами даних з поганим моделюванням та / або умовами іменування, то Linq-SQL відображатиме ці небажані структури та імена вашим класам. Однак NHibernate може приховати цей безлад з картографами даних.

У проектах Greenfield, де бази даних мають хороші імена та низьку складність, Linq-SQL може бути хорошим вибором.

Однак ви можете використовувати Fluent NHibernate з автоматичним відображенням для цієї ж мети з картографуванням як звичайне. У цьому випадку ви не турбуєтесь про будь-які картографи даних з XML або C # і дозволяєте NHibernate генерувати схему бази даних від ваших організацій на основі конвенції, яку ви можете налаштувати.

З іншого боку, крива навчання Linq-to-SQL менша, ніж NHibernate.


0

Або ви можете використовувати проект Castle ActiveRecords. Я використовую це протягом короткого часу, щоб збільшити новий код для застарілого проекту. Він використовує NHibernate і працює над активною схемою запису (дивно, даючи назву, яку я знаю). Я не пробував, але припускаю, що як тільки ви користуєтесь ним, якщо відчуваєте необхідність перейти до підтримки NHibernate безпосередньо, це було б не надто багато для частини або всього вашого проекту.


0

Як ви писали "для людини, яка не використовувала жодної з них" LINQ до SQL проста у використанні, тому будь-яка людина може її легко використовувати. Це також підтримує процедури, що допомагає більшу частину часу. Припустимо, ви хочете отримати дані з декількох таблиць, потім напишіть процедуру та перетягніть цю процедуру на конструктор, і вона створить все для вас. Припустимо, назва вашої процедури "CUSTOMER_ORDER_LINEITEM", яка отримує запис з усіх цих трьох таблиць, а потім просто запишіть

MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();

Ви також можете використовувати об'єкт запису в циклі foreach, який також не підтримується NHibernate

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.