Недавно пришлось делать сравнение NHiberante и EF4. Стоит отметить, что мой личный опыт включает в себя только использование NHibernate, и остальные изыскание проводились исключительно с позиции стоит ли EF4 усилий по своему изучению. Вкратце преимущество каждого перечислены ниже.
Преимущества NHibernate
Преимущества EF
Преимущества NHibernate
- Пакетное чтение (MulityQuery, Future)
- Пакетная запись, настраиваемая в конфиге.
- Пакетная ленивая загрузка коллекций, сокращающая проблему N +1
- Сверхленивая загрузка коллекций (Order.OrderLines.Count приводит к select count(*) )
- Возможность постраничной выборки и фильтрации коллекций.
- Разнообразные способы выборки: HQL, ICriteria, QueryOver, LINQ, SQL(включая хранимые процедуры) и трансформации результатов с использованием IResultTransformer.
- Кеш второго уровня.
- Большое количество точек расширения, открывающих широкие возможности по модификации поведения
- Как следствие из предыдущего пункта, существует большое большое количество расширяющих фреймворков. Примеры:
- NHibernate.Envers - аудит
- NHibernate.Validator - думаю понятно :)
- NHiberante.Search - Полнотекстовый поиск с использованием Lucene.Net
- NHibernate.Shards - горизонтальное масштабирование приложений.
- Rhino.Security - библиотека для разграничения прав доступа.
- Разнообразные способы маппинга объектов на бд:
- xml
- аттрибуты
- маппинг кодом (2 отдельных фреймворка + встроенная поддержка)
- по классам
- по соглашениям.
- Более мощный язык объектных запросов (HQL vs Entity SQL), позволяющий выполнять объектные DML-команды без загрузки объектов в память.
- Встроенная поддержка для логгирования генерируемых sql-команд.
- Более 10 разнообразных id-генераторов, включая наиболее эффективные для ORM HiLo и guid.comb.
- Возможность маппинга разнообразных пользовательских типов (шифрованные строки, локализованные свойства, запись Enum как строки, и многое другое)
- Поддержка readonly свойств.
- Поддеркжа коллекций элементов (например IList<int>)
- Поддержка маппинга словарей (Dictionary).
- Сильное сообщество программистов.
Преимущества EF
- Лучшая поддержка LINQ.
- Свойства объектов не обязательно должны быть виртуальными.
- Microsoft.
- Наличие визуального редактора от Microsoft.
Мой выбор очевиден, NHibernate. Остальное решать вам.
Интересно, что бы подумала @julielerman, увидев, что для EF оставили 4 пункта..
ОтветитьУдалитьВидимо, лопнула бы от завивисти. http://thedatafarm.com/blog/data-access/what-do-you-want-to-see-in-entity-framework/ - большая часть хотелок пользователей уже есть в NHibernate.
ОтветитьУдалитьЧасть 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 хотя задокументировано это плохенско.
Часть 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#) - так мне оказалось более внятно все.
Пишу это все просто в качестве контр-поста, так как думаю всем кто инетерсуется темой важно знать несколько мнений.