Страницы

вторник, 25 октября 2011 г.

NHibernate vs Entity Framework 4.

  Недавно пришлось делать сравнение NHiberante и EF4. Стоит отметить, что мой личный опыт включает в себя только использование NHibernate, и остальные изыскание проводились исключительно с позиции стоит ли EF4 усилий по своему изучению. Вкратце преимущество каждого перечислены ниже.


Преимущества NHibernate
  1. Пакетное чтение (MulityQuery, Future)
  2. Пакетная запись, настраиваемая в конфиге. 
  3. Пакетная ленивая загрузка коллекций, сокращающая проблему N +1 
  4. Сверхленивая загрузка коллекций (Order.OrderLines.Count приводит к select count(*) )
  5. Возможность постраничной выборки и фильтрации коллекций. 
  6. Разнообразные способы выборки: HQL, ICriteria, QueryOver, LINQ, SQL(включая хранимые процедуры) и трансформации результатов с использованием IResultTransformer.
  7. Кеш второго уровня. 
  8. Большое количество точек расширения, открывающих широкие возможности по модификации поведения 
  9. Как следствие из предыдущего пункта, существует большое большое количество расширяющих фреймворков. Примеры:
    • NHibernate.Envers - аудит 
    • NHibernate.Validator - думаю понятно :)
    • NHiberante.Search - Полнотекстовый поиск с использованием Lucene.Net
    • NHibernate.Shards - горизонтальное масштабирование приложений. 
    • Rhino.Security - библиотека для разграничения прав доступа. 
  10. Разнообразные способы маппинга объектов на бд:
    • xml
    • аттрибуты
    • маппинг кодом (2 отдельных фреймворка + встроенная поддержка)
      • по классам
      • по соглашениям.
  11. Более мощный язык объектных запросов (HQL vs Entity SQL), позволяющий выполнять объектные DML-команды без загрузки объектов в память. 
  12. Встроенная поддержка для логгирования генерируемых sql-команд. 
  13. Более 10 разнообразных id-генераторов, включая наиболее эффективные для ORM HiLo и guid.comb.
  14. Возможность маппинга разнообразных пользовательских типов (шифрованные строки, локализованные свойства, запись Enum как строки, и многое другое)
  15. Поддержка readonly свойств. 
  16. Поддеркжа коллекций элементов (например IList<int>)
  17. Поддержка маппинга словарей (Dictionary).
  18. Сильное сообщество программистов. 



Преимущества EF
  1. Лучшая поддержка LINQ.
  2. Свойства объектов не обязательно должны быть виртуальными.  
  3. Microsoft.
  4. Наличие визуального редактора от Microsoft.
Мой выбор очевиден, NHibernate. Остальное решать вам. 

4 комментария:

  1. Интересно, что бы подумала @julielerman, увидев, что для EF оставили 4 пункта..

    ОтветитьУдалить
  2. Видимо, лопнула бы от завивисти. http://thedatafarm.com/blog/data-access/what-do-you-want-to-see-in-entity-framework/ - большая часть хотелок пользователей уже есть в NHibernate.

    ОтветитьУдалить
  3. Часть 1
    Сейчас собираюсь переходить с NHibernate на EF4 по следующим причинам (возможно что для вас
    это все наоборот), при этом с NHibernate я прожил уже без малого 6 лет и весь код заточен под него:
    1. Преимущества NHibernate кореннятся в весьма сложных инструментах типа пакетной загрузки, которые крайне редко можно по делу применить в типовом бизнес приложении. По сути каждый раз когда я пытался (ну может я дурачек) применить по делу в итоге приходил к более простым решениям.
    2. В NHibernate не по-детски головомойная система организации сессий и управлений ими, особенно в случае мапинга одной и той же модели сразу в несколько баз, в итоге я написал собственную библиотеку врапперов всяких которые по дизайну как теперь выяснилось - те же DbContext что и в EF только в профиль
    3. Расширяемость та еще - несмотря что точек расширения много API у них и цикл жизни (особенно по тем, которые реально касаются работы с данными) - те еще. Гораздо проще на собственном мидл леере прописать правила и их юзать, чем пихать это в ORM
    4. Из баз нужны только SQLServer,PostGres и изредка Oracle - так что мне поставщиков данных хватает что там и там.
    5. HQL не БОЛЕЕ ПРОДВИНУТЫЙ ЯЗЫК - ENTITY SQL КУДА БОГАЧЕ ПО КОНСТРУКЦИЯМ для SELECT, продвинутость его только в том что
    а) там есть DML и что обработчик HQL
    б) сам конвертит результат в коллекцию типизированных объектов
    но при осмыслении этого момента 1) DML из HQL - не слишком часто используемая вещь, обычно все же (ну я лично) либо использую Save на загруженном объекте с проверкой всех правил, либо же выполняю хранимые процедуры, ибо считаю что DML это удел все же готового и продуманного репозитария, а не динамических строковых запросов 2) ДА, НЕУДОБНО и приходится использовать ObjectContext.Translate, но c другой стороны EntitySql возвращает внятный EntityDataReader при выполнении запроса а не невнятный ArrayList без метаданных, как это делает HQL обработчик
    6. Визуальный редактор сразу выбрасывается на помойку, так как реальные пацаны работают только с POCO и с Code-First и тут несмотря на все рассуждения - в EF 4(про 1-2-3 мы понятно не говорим) - гораздо более четкая и продуманная поддержка для Code-First чем в NHibernate - в NHIbernate есть несколько конкурирующих классов для Poco-мапинга из кода+ POCO фальшивые - все должно быть завиртуализовано и всегда в серьезном решении на выходе прокси, причем если в смеси у вас создание-чтение-запись, то будет смесь прокси и простые экземпляры. В EF codefirst тоже не без изъянов но более внятный. Плюс хотя многие не знают этого Entity SQL вполне себе работает с Code-First хотя задокументировано это плохенско.

    ОтветитьУдалить
  4. Часть 2

    Отсюда при всем уважении к автору поста, без всякого отрицания (кроме богатости HQL) пунктов про NHibernate все же позволю себе поправить преимущества EF:
    1. Microsoft - да, это вроде как плохо, но зато в составе поставки .NET и соответственно еще и будет включено в Mono и это системные либы+одна дополнительна, а NHib как любой открытый проект тянет еще кучу доп расширений невнятного свойства еще со всякого 3d party - вы посмотрите сами что у вас будет потом в папке BIN - и ByteCode и много еще всего
    2. РЕДАКТОР НЕ ПРЕИМУЩЕСТВО - выкидывайте на помойку
    3. LINQ - да, это неплохо, когда пишется готовый репозитарий, независимый от БД
    4. Реальные POCO - да, EF лучше работает в режиме Code-First+Poco
    5. DbContext vs ISession - однозначный проигрыш ISession - в плане управления базовые классы доступа EF удобнее. DBContext позволяет проще моделировать разные циклы жизни сессий и транзакций и особенно при использовании нескольких целевых БД для одной модели
    6. В списке про NHib приведены механизмы HQL, ICriteria, QueryOver, LINQ, SQL(включая хранимые процедуры) и трансформации результатов с использованием IResultTransformer) - понять не могу чем это круче набора Entity SQL, Entity Linq , Linq for SQL и то, что никакого ResultTransformer собственно не требуется??? То есть я не скажу, что средства чтения данных в EF как-то сильно и неимоверно круче, хотя Entity SQL богаче HQL, но говорить что EF сильно отстает - не приходится
    7. Расширяемость EF ориентирована на перекрытие классов и я не думаю, что эта модель сильно ущербнее обработки событий и хуков, которые есть в NHib, но допустим, но вот что точно более удобно в EF, так это мониторинг итоговых SQL запросов которые он шлет, в NHib это исполнено менее внятно
    8. ДИНАМИЧЕСКОЕ НАЗНАЧЕНИЕ для контекста ленивый/не ленивый, с трекингом/без трекинга, с кэшем/ без кэша. Подскажите ка мне как в случае с NHib в модели с Lazy могу для конкретного запроса этот Lazy отключить для например оптимизации???

    Отсюда мое резюме:
    За 6 лет использования Nhib я практически не пользовался с его наворотами, зато терпел дополнительные сборки, сложные конфиги, тяжелый code-first, писал свои врапперы, чтобы обойти его острые углы с сессиями (особенно в случае с MVC, когда нужно держать сессии на веб запрос, но иметь возможности использовать их пул и т.п.).
    Я шибко доволен был всегда тем не менее NHib,
    но в лице EF 4 я вижу вполне себе внятный ORM движок, который двигается в ядро .NET|MONO, который явно многое взял из того же NHib и при этом мне не придется юзать левые библиотеки , где будет проще с конфигурацией code-first и poco, где не без гемороя но легко применить весьма навороченный Entity SQL - мой выбор - даже ценой затрат на миграцию перейти на EF 4 так как NHib для меня двигается не в нужном мне направлении - а движется он в сторону наворотов (которые мне особо не нужны) и обрастания кучей левых либ (как это бывает в Java среде очень часто) - которые вроде и отношения не имеют к ядру NHib но без которых жить не получается - всякие поставщики прокси, обработчики внутренних событий и проч.

    P.S. Я не работаю на Microsoft и вообще не их почитатель, но кое что они сделали с толком Excel и .NET и EF 4 мне кажется тоже весьма неплохой штукой, хлеб он свой оправдывает.
    P.S.2 - вообще решил при развитии ядра своих решений полностью уйти с внешних либ в итоге избавляюсь от log4net (написал свой эквивалент), Nhibernate (миграция на EF), MonoRail (сначала дернул на MS MVC, но он тоже так себе - написал свое), Castle Windsor (посмотрел MEF сначала - но там бред, написал свой контейнер), Boo - (сделал DSL на основе собственного языка BXL (питоноподобный синтаксис полностью эквивалентный XML по смыслу конструкций, только лаконичнее засчет отсутвия лишних скобок, кавычек и разделителей) +XSLT(->CS)+компилятор C#) - так мне оказалось более внятно все.
    Пишу это все просто в качестве контр-поста, так как думаю всем кто инетерсуется темой важно знать несколько мнений.

    ОтветитьУдалить