Відповіді:
LINQ в SQL змушує використовувати шаблон таблиці за класом. Переваги використання цього шаблону полягають у тому, що його швидко та просто реалізувати, і для того, щоб ваш домен працював на основі існуючої структури бази даних, потрібно дуже мало зусиль. Для простих застосувань це цілком прийнятно (а часто навіть краще), але для більш складних застосувань розробники часто пропонують використовувати замість цього шаблон дизайну, керований доменом (що полегшує NHibernate).
Проблема з шаблоном таблиці на клас полягає в тому, що структура вашої бази даних має прямий вплив на дизайн вашого домену. Наприклад, скажімо, у вас є таблиця "Клієнти" із наступними стовпцями для зберігання основної інформації про клієнта:
Скажімо, ви хочете додати стовпці для поштової адреси клієнта, щоб ви додали в наступні стовпці до таблиці Клієнти:
Використовуючи LINQ для SQL, об’єкт Клієнта у вашому домені тепер матиме властивості для кожного з цих восьми стовпців. Але якби ви дотримувались схеми дизайну, керованої доменом, ви, ймовірно, створили клас адреси та мали б ваш клас Клієнта два властивості адреси, одну для поштової адреси та одну для їх поточної адреси.
Це простий приклад, але він демонструє, як модель таблиці за класом може призвести до дещо смердючої області. Зрештою, це залежить від вас. Знову ж таки, для простих додатків, які просто потребують базової функціональності CRUD (створювати, читати, оновлювати, видаляти), LINQ до SQL ідеально підходить через простоту. Але особисто мені подобається використовувати NHibernate, оскільки це сприяє більш чистому домену.
Редагувати: @lomaxx - Так, я використав приклад спрощений і міг бути оптимізований для роботи з LINQ в SQL. Я хотів, щоб це було максимально базовим, щоб загнати додому пункт. Справа, однак, існує декілька сценаріїв, коли структура вашої бази даних визначає вашу структуру домену було б поганою ідеєю або, принаймні, призводить до неоптимального дизайну ОО.
Два моменти, які до цього часу були пропущені:
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 також починає виглядати як реальна опція.
@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 може
зробити це автоматично для вас.
Fluent NHibernate може генерувати ваші картографічні файли на основі простих конвенцій. Немає XML-написання та сильно набрано.
Нещодавно я працював над проектом, де нам потрібно було з міркувань продуктивності перейти з Linq на SQL на NHibernate. Особливо спосіб L2S матеріалізації об'єктів здається повільнішим, ніж дефіт NHibernate, і управління змінами теж досить повільне. І може бути важко вимкнути управління змінами для конкретних сценаріїв, де це не потрібно.
Якщо ви збираєтесь використовувати ваші особи, відключені від DataContext - наприклад, у сценаріях WCF - у вас можуть виникнути проблеми з підключенням їх до DataContext для оновлення змін. У мене з цим не було проблем з NHibernate.
Що я пропущу з L2S - це здебільшого генерація коду, яка постійно оновлює відносини на обох кінцях об'єктів. Але я думаю, що є кілька інструментів для NHibernate, щоб зробити це і там ...
.ObjectTrackingEnabled = false
на ваш рахунок DataContext
вирішиться проблема відстеження змін. Поки ви купуєте схему одиничної роботи і не хочете робити DDD, Linq-до-SQL дійсно забезпечує.
Чи можете ви уточнити, що ви маєте на увазі під "LINQ"?
LINQ - це не технологія доступу до даних, це лише мовна функція, яка підтримує запити як нативну конструкцію. Він може запитувати будь-яку об'єктну модель, яка підтримує конкретні інтерфейси (наприклад, IQueryable).
Багато людей відносять LINQ до SQL як LINQ, але це зовсім не правильно. Щойно Microsoft випустила LINQ To Entities з .NET 3.5 SP1. Крім того, NHibernate має інтерфейс LINQ, тому ви можете використовувати LINQ та NHibernate для отримання своїх даних.
Під LINQ я припускаю, що ви маєте на увазі LINQ для SQL, оскільки LINQ сам по собі не має пов'язаних з ним баз даних. Це просто мова запиту, яка містить човен синтаксичного цукру, щоб він виглядав SQL-ish.
У самих основних базових прикладах, схоже, NHibernate та LINQ для SQL вирішують одну і ту ж проблему. Як тільки ви пройдете, ви незабаром зрозумієте, що NHibernate має підтримку безлічі функцій, які дозволяють створювати справді багаті моделі доменів. Існує також проект LINQ to NHibernate, який дозволяє використовувати LINQ для запиту NHibernate приблизно так само, як і LINQ для SQL.
Спочатку давайте розділимо дві різні речі: Моделювання баз даних стосується даних, а об'єктне моделювання стосується сутностей та відносин.
Перевага Linq-SQL полягає в швидкому генеруванні класів із схеми бази даних, щоб їх можна було використовувати як активні об'єкти запису (див. Визначення схеми дизайну активних записів).
Перевага NHibernate полягає в тому, щоб дозволити гнучкість між моделюванням об'єктів та моделюванням баз даних. База даних може бути змодельована так, щоб найкраще відображати ваші дані, наприклад, враховуючи ефективність роботи. У той час як ваше моделювання об'єктів найкраще відображатиме елементи бізнес-правила, використовуючи такий підхід, як «Управління доменом». (див. коментар Кевіна Панга)
З застарілими базами даних з поганим моделюванням та / або умовами іменування, то Linq-SQL відображатиме ці небажані структури та імена вашим класам. Однак NHibernate може приховати цей безлад з картографами даних.
У проектах Greenfield, де бази даних мають хороші імена та низьку складність, Linq-SQL може бути хорошим вибором.
Однак ви можете використовувати Fluent NHibernate з автоматичним відображенням для цієї ж мети з картографуванням як звичайне. У цьому випадку ви не турбуєтесь про будь-які картографи даних з XML або C # і дозволяєте NHibernate генерувати схему бази даних від ваших організацій на основі конвенції, яку ви можете налаштувати.
З іншого боку, крива навчання Linq-to-SQL менша, ніж NHibernate.
Або ви можете використовувати проект Castle ActiveRecords. Я використовую це протягом короткого часу, щоб збільшити новий код для застарілого проекту. Він використовує NHibernate і працює над активною схемою запису (дивно, даючи назву, яку я знаю). Я не пробував, але припускаю, що як тільки ви користуєтесь ним, якщо відчуваєте необхідність перейти до підтримки NHibernate безпосередньо, це було б не надто багато для частини або всього вашого проекту.
Як ви писали "для людини, яка не використовувала жодної з них" 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