Entity Framework 4 vs NHibernate

Много говорилось о первой версии Entity Framework в Интернете (также в stackoverflow), и ясно, что это был не лучший выбор, когда у нас уже есть лучшая альтернатива, например, NHibernate. Но я не могу найти хорошее сравнение Entity Framework 4 и NHibernate. Мы можем сказать, что сегодня NHibernate является лидером среди всех .NET ORM, но можем ли мы ожидать, что Entity Framework 4 вытеснит NHibernate из этой позиции. Я думаю, что если Microsoft действительно ввела очень хорошие функции в EF4, это может дать хорошую конкуренцию NHibernate, поскольку она имеет интеграцию с Visual Studio, с которой легче работать, и предпочтение всегда предоставляется продуктам MS в большинстве магазинов.

EF4 имеет готовый ответ в отношении разработки n-уровня в «объектах самоконтроля». Никто не выпустил сопоставимый код для NHib.

NHIB имеет множество функций, которые не упоминались как часть EF4. К ним относятся интеграция кеша второго уровня. Он также обладает большей гибкостью в отображении наследования, лучшей интеграцией с хранимыми функциями procs / database / настраиваемыми SQL / триггерами, поддержкой свойств формулы и т. Д. ИМО в основном просто более зрелая, как ОРМ.

Обновление: я не использовал Entity Framework с версии 4.0, поэтому мой ответ может быть устаревшим. Я все еще использую NH или чистый ADO .NET в своих проектах. И я даже не хочу смотреть, что нового в EF с 4.0, потому что NH работает отлично.

На самом деле довольно легко сравнивать их, когда вы использовали оба. Есть некоторые серьезные ограничения с EF4, я могу назвать некоторые, с которыми я столкнулся сам:

Проблемы EF4:

  • Eager загружает и формирует результат : система загрузки EF4 с нетерпением (Include («Путь»)) генерирует неправильный SQL с циклом JOIN, который будет выполнять тысячи (не буквально) время медленнее для отношений «многие ко многим», а затем записывать SQL (это эффективно непригодным для использования).
  • Материализатор не может материализовать связанные объекты : если вы думаете, что можете преодолеть предыдущую проблему, предоставив собственный SQL-запрос, вы ошибаетесь. EF4 не может материализовать (сопоставить) связанные объекты с JOIN SQL-запросом, он может загружать только данные из одной таблицы (поэтому, если у вас есть Order.Product, SELECT * FROM order LEFT JOIN Продукт будет инициализировать только объект Order, Product останется null, думал, что все необходимые данные извлекаются в запросе для его инициализации). Это можно преодолеть, используя дополнение сообщества EFExtensions, но код, который вам придется писать для этого, действительно уродлив (я пробовал).
  • Self-Tracking Entities : многие говорят, что объекты для самостоятельного отслеживания являются classными для разработки N-уровня, включая верхний ответ в этой теме. Думал, что я даже не попросил их, я могу сказать, что они не являются. Каждый вход может быть подделан, вы не можете просто принимать изменения, которые пользователь отправляет вам, и применять их к базе данных, почему бы не дать прямым данным пользователя базовый доступ? Любой способ, которым придется загружать пользователя данных, должен измениться с БД, проверить, что он существует | не существует, проверяет разрешения и т. Д. И т. Д. Вы не можете доверять пользователю в состоянии сущности, которую он отправляет на сервер, вы все равно должны загружать этот объект из БД и определять его состояние и другие вещи, поэтому эта информация бесполезна, как и объекты самоконтроля, если вы не используете частную доверенную систему n-уровня для внутреннего использования, и в этом случае, возможно, вы могли бы дать простое Доступ к БД. (Thats мои мысли о ST Entities и N-tire, я не очень разбираюсь в N-Tier, так что это может измениться, если я неправильно понял что-то здесь, комментирую это)

  • Logging, Events, интеграция бизнес-логики: EF4 похож на черный ящик, он что-то делает, и вы не представляете, что он делает. Существует только одно событие OnSavingChanges, где вы можете поместить некоторую бизнес-логику, которую нужно запустить, прежде чем что-то произойдет с БД, и если вам нужно применить некоторые изменения к бизнес-объектам до того, как что-то произойдет, вам придется копать в ObjectStateManager, и это действительно уродливо , код может стать огромным. Если вы, например, используете шаблон репозитория и что должны быть уведомлены об изменениях, внесенных в БД в чистом объекте, вам будет трудно это сделать с помощью EF.

  • Расширяемость: весь код EF является частным и внутренним, если вам что-то не нравится (и вам не понравится LOT, если вы серьезно относитесь к использованию EF), никоим образом вы не измените это простым способом, на самом деле я уверен проще написать собственный ORM с нуля (я сделал), а затем сделать работу EF по мере необходимости. В качестве примера рассмотрим источник EFExtensions, он основан на методах расширений и разных «хаках», чтобы сделать EF более удобным для использования, а код довольно уродлив (и это не ошибка авторов, когда все в EF является частным, это единственное способ его расширения).

Я могу продолжать писать плохие вещи о EF и как мне было больно работать с ним примерно на 20 страниц, и, возможно, я это сделаю.

Как насчет NHibernate? Это совершенно другой уровень, это похоже на сравнение PHP с C #, EF4 похож на Stone-age, это похоже на то, что EF на 10 лет отстает от NHibernate в развитии, и на самом деле это Hibernate был запущен в 2001 году. Если у вас есть свободное время научиться и включить Nhibernate, сделайте это.

Вот что. На мой взгляд, NHibernate и Entity Framework действительно предназначены для двух разных аудиторий. NHibernate был бы моим выбором в создании системы со сложными отображениями, формулами и ограничениями (в основном, что-либо предприятие). Если бы я хотел, чтобы я работал с простым доступом к данным, я бы использовал Entity Framework или LINQ-to-SQL. NHibernate не имеет четкого «перетаскивания», как EF. У обоих есть свои сильные стороны и недостатки. Сравнивая их с яблоками и яблоками, откровенно говоря, никуда не денется.

Если вы считаете, что когда-либо захотите запустить свой код в Mono, NHibernate, вероятно, лучший выбор, независимо от того, что говорят контрольные списки функций …

Редактировать, 13.08.2012:

Entity Framework была открыта с открытым исходным кодом и теперь включена в Моно по 2.11.3. Этот ответ теперь устарел и на него нельзя положиться.

http://weblogs.asp.net/scottgu/archive/2012/07/19/entity-framework-and-open-source.aspx

Я считаю, что EF4.0 прошел долгий путь с 1.0 и догоняет Nhibernate в функциональности, но он еще не все.

Однако это Microsoft, из коробки и 100% того, что нужно 95% приложений. Тем не менее, NHibernate делает то же самое в течение многих лет. Приходите версия 5.0 или 6.0 может догнать или даже превзойти NHibernate.

Вот мой совет – если у вас есть время, чтобы изучить оба, сделайте это. Существует несколько причин выбрать один из них. Если вы пишете код для корпорации, реалистично ожидать, что смогут быть сотрудниками, которые будут знакомы с EF, так как это во всех книгах и в том, что дети учатся в колледже. Если EF будет отвечать вашим требованиям (думать о один долго и упорно, прежде чем просто сказать да это), то это прекрасно подходит сейчас, и через несколько лет он может (ок, скорее всего, будет) превзойдет NHibernate.

NHibernate – очень зрелый продукт с несколькими годами на EF и, скорее всего, сделает все, что вы когда-либо захотите, а затем и некоторые. Это было лучшее ORM какое-то время, и многие люди его используют.

Я думаю, что тот факт, что EF 4 будет иметь возможность использовать POCO и отложенную ленивую загрузку, будет очень большой. Я определенно мог видеть, как он набирает силу с новым выпуском.

Существует очевидная тенденция увеличения популярности EF по сравнению с NHibernate, см. Картину.

NHibernate vs Entity Framework

Мои 2 цента: мы используем ef на нашем настольном клиенте для некоторых cahing и т. Д. – без высоких нагрузок. NHib на стороне сервера – использование сессий без учета состояния, генерация и партии hilo. Является довольно быстрым вложением сообщений 3k + в секунду в секунду. Также он очень гибкий и поддерживает множество dbs, которые имеют решающее значение для нашего продукта.

Самый простой подход – сопоставление непосредственно с хранимыми процедурами с комбинацией Linq для логического уровня. Нет xml. Создавайте sql только для интересных запросов, которые менее часто используются или не подходят для хранимых процедур.

Объекты загружаются и хранятся через стандартные SP. Этот подход позволяет использовать два входа в sql. Один для доступа к classу через SP (разрешения только для выполнения) и один для логического модуля linq, который обеспечивает прямой доступ к таблице.

Выбор между ORM по популярности – это не лучшая вещь. Я пытался переехать в EF последние 2 года, и все, что я могу сказать, почему, черт возьми, я все еще пытаюсь?

ATM моя точка зрения о EF: «Это сделано для действительно маленьких довольно крошечных битовых систем с не более чем тремя таблицами с отношением менее 1 (лучше 0)».

И почему я так думаю? 1. Попробуйте обновить отключенный график и увидеть свою модельную царапину;

  1. Попробуйте сделать TPH с глубокими унаследованными деревьями, и вы обнаружите, что вас распутывают на одну иерархию или система сломается.

  2. Попытайтесь сделать более громоздкие запросы и наблюдайте, как вся система съедает стек: D … переполнения происходят очень часто.

  3. Типы данных XML XML основаны на расширениях или наиболее «ненавидящих» свойствах NotMapped … и это еще хуже.

  4. Попробуйте добавить SQL-запрос в Linq для более мелких запросов, и вы сломаете стену lol.

  5. И последнее и самое главное, EF не поддерживает формулу свойств («потрясающие ресурсы NH для устаревших баз данных») и не поддерживает сопоставления сложных типов для одной таблицы и связанных таблиц.

Это мой 10cc.

  • Какова проблема с запросом SELECT N + 1?
  • Bypass GeneratedValue в спящем режиме (данные объединить не в db?)
  • В чем разница между fetch = "EAGER" и fetch = "LAZY" в доктрине
  • Когда Hibernate сбрасывает сеанс, как он решает, какие объекты в сеансе загрязнены?
  • ORM для DELPHI win32
  • Классы classов Hibernate должны быть Serializable?
  • Примитив или shell для первичных ключей спящего режима
  • Как следует использовать равенства и hash-код при использовании JPA и Hibernate
  • Можно ли динамически определять имена столбцов в Hibernate / JPA?
  • Я обнаружил, что JPA, или, похоже, не поощряет шаблон DAO
  • JPQL Создать новый объект в Select Statement - избегать или объявлять?
  • Давайте будем гением компьютера.