Entity Framework Голосование о недоверии - актуально в .NET 4? - PullRequest
60 голосов
/ 08 марта 2010

Я выбираю ORM для большого проекта и был полон решимости перейти на ADO.NET Entity Framework, в частности его новую версию, поставляемую с .NET 4. Во время поиска информации по EF я наткнулся на ADO .NET Entity Framework Голосование о недоверии , которое я не знаю, как принять.

«Голос недоверия» был написан где-то в 2008 году, чтобы убедить Microsoft прислушиваться к конкретной критике EF v1.

Неясно, остаются ли в силе утверждения, поданные в «Голде о недоверии» (в .NET 4), и достаточно ли они серьезны, чтобы использовать другие решения. NHibernate является зрелой альтернативой, но я не знаю, какие проблемы это приносит. Я обычно больше склоняюсь к решению Ms, в основном потому, что могу рассчитывать на интеграцию с VS и на поддержку их разработчиков.

Буду признателен за примеров того, как проблемы, упомянутые в "Голосе за недоверие", влияют на проекты в реальном мире. Что еще более важно, остаются ли в EF все еще актуальными утверждения для .NET 4?

Ответы [ 4 ]

64 голосов
/ 08 марта 2010

Я всегда чувствовал, что многое из того, что лежало в основе «вотума недоверия», было попыткой использовать EF, как если бы это был клон NHibernate. Это не так, и даже в EF 4 попытка использовать EF, как если бы это был подделка NHibernate, вероятно, закончится неудачей, хотя вы можете продвинуться немного дальше, прежде чем потерпеть неудачу. В качестве тривиального примера, большинство людей используют LINQ в NHibernate на минимальной основе, если вообще используют, тогда как я не думаю, что вы сможете работать с EF вообще , если не будете использовать LINQ достаточно интенсивно.

С другой стороны, я довольно успешно использовал EF 1 на своих собственных условиях и сумел не допустить, чтобы претензии, которые люди делают в блогах, мешали ему работать. Я с нетерпением ожидаю использования многих новых функций в EF 4, но я был бы рад в любое время поработать над хорошо структурированным проектом EF 1. (Впрочем, я тоже рад работать с NHibernate и не стал бы критиковать его за то, что он не действует как EF.)

Итак, я пытаюсь несколько деликатным образом предположить, что прежде чем вы сможете решить, «остаются ли в силе утверждения, поданные в ходе голосования о недоверии (в .NET 4) ...», вы должны сначала решить, если эти утверждения были когда-либо действительными для вас и то, как вы работаете. Если ваше личное понимание O / R привязано к NHibernate, то EF 4, вероятно, все еще будет казаться второсортный для вас. Если, с другой стороны, вы готовы изучить способ работы с EF, то, вероятно, даже EF 1 покажется вам лучше, чем вы слышали.

Для непосредственного рассмотрения претензий "недоверия" и изучения их существа и изменений в EF 4:

НЕПРАВИЛЬНЫЙ ФОКУС ДАННОГО АСПЕКТА СУЩЕСТВ ПРИВОДИТ К АРХИТЕКТУРАМ ДЕГРАГИРОВАННОГО СУЩНОСТИ:

Это неправильное понимание модели данных сущностей Entity Framework. (Или, если хотите, разница во мнениях.) Но в любом случае, это особенность, а не ошибка. Entity Framework разработан для более общего случая услуг передачи данных, а не только для O / R моделирования в частности. Внедрение поведения в сущности, возвращаемые из службы данных, приводит к катастрофе в стиле CORBA. В отличие от ORM, где вы в какой-то степени застряли с любым типом, выходящим из черного ящика ORM, с моделью Entity Framework, которую вы должны проецировать на бизнес-типы. В этом случае сопоставленные типы сущностей никогда не будут материализованы.

Это существенное различие между моделью Entity Framework и многими другими ORM. Лично я нахожу, что отделение бизнес-поведения от O / R-сопоставления несколько чище, чем их объединение. Вы не должны соглашаться с этой идеей, но это явно дизайнерское решение, а не недосмотр.

ДОПОЛНИТЕЛЬНЫЙ КОД, НЕОБХОДИМЫЙ ДЛЯ СДЕЛКИ С НЕДОСТАТОЧНЫМ ЗАГРУЗКОМ:

EF 4, к лучшему или худшему, имеет ленивую загрузку.

Я говорю «к лучшему или к худшему», потому что ленивая загрузка позволяет очень легко генерировать лишние запросы к базе данных. Это прекрасно работает, пока вы внимательно следите за тем, что происходит под капотом, но большинство людей этого не делают. Я считаю проекция лучшей альтернативой отложенной загрузке, активной загрузке или явной загрузке в большинстве случаев.

И все же бывают случаи, когда ленивая загрузка удобна. Так что я рад видеть его добавленным в EF 4.

ОБЩАЯ ПРАКТИКА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ КАНОНИЧЕСКОЙ МОДЕЛИ ПРОТИВОРЕЧИЯ:

Трудно понять, что с этим делать, так как часть вспомогательного текста даже не согласована с английским, например ::1010*

Подход к ошибочным каноническим моделям не был сложным из-за отсутствия сложных инструментов в соответствии с Entity Framework.

В этом разделе , кажется, предполагается, что Entity Framework предъявляет какие-то требования или, по крайней мере, сильное смещение к использованию единой канонической модели данных для сложной системы. Я не уверен, что согласен, но это трудно сказать, учитывая отсутствие какого-либо конкретного примера в этом разделе. Поэтому я расскажу вам свои предубеждения по этому вопросу, и вы можете согласиться или не согласиться со мной:

Часто ошибочно использовать одну модель для большой системы, в зависимости от того, насколько велика система на самом деле. Однако ничто в Entity Framework не требует использования одной модели. С другой стороны, Entity Framework, особенно в версии 1, делает все возможное, чтобы упростить объединение нескольких моделей.

Теперь одно большое приложение для сложной системы может быть такой же большой ошибкой, как одна большая модель данных. Таким образом, было бы неправильно для Entity Framework упрощать объединение множества крошечных моделей в одно слишком большое приложение; это просто заменит одну проблему на другую.

С другой стороны, я думаю, что имеет смысл облегчить построение большой системы из служб, разделенных таким образом, чтобы удовлетворить проблемной области. Я думаю, что службы данных WCF, отдельная технология от Entity Framework, но очень хорошо поддерживающая Entity Framework, полезны для этого.

Я думаю, что Entity Framework в некоторых будущих версиях может упростить объединение двух или трех моделей в одно приложение, когда это необходимо. Вы можете сделать это сейчас, но есть некоторая ручная работа. Но, как я уже сказал выше, я бы не хотел «исправлять» проблему чрезмерно большой модели данных, облегчая / поощряя создание чрезмерно большого приложения.

ОТСУТСТВИЕ НЕЗНАНИЯ НА ЧЕЛОВЕКЕ ПРИЗНАВАЕТ БИЗНЕС-ЛОГИКУ, ЧТОБЫ ЧУВСТВОВАТЬ ЧИТАТЬ, НАПИСАТЬ И ИЗМЕНЯТЬ, ВЫЗЫВАТЬ ИЗМЕРЕНИЯ РАЗВИТИЯ И ТЕХНИЧЕСКОГО ОБСЛУЖИВАНИЯ, ЧТОБЫ УВЕЛИЧИТЬСЯ С ПОВЫШЕННОЙ СКОРОСТЬЮ

В этом разделе приводятся претензии, которые я считаю ошибочными:

Entity Framework поощряет анти-паттерн Anemic Domain Model, препятствуя включению бизнес-логики в классы сущностей.

Смотри выше. Я думаю, что работа типов сущностей заключается в отображении между реляционным пространством в пространстве объектов. Согласно принципу единой ответственности, эти типы должны быть изменены только при изменении их единственной работы. Если бизнес-процессы меняются, то это ответственность, не связанная с отображением O / R. Возможно, ограничения других ORM создают технический барьер для разделения этих обязанностей. Можно изменить правила, когда технология диктует, если стоимость дизайна слишком высока. Но я решительно поддерживаю подход типов сущностей без поведения.

В своем текущем состоянии классы сущностей EF не могут быть эффективно проверены модулем независимо от базы данных.

Это просто неправильно . Кто бы ни написал это, не понял, о чем они говорили. Ни один из наших модульных тестов никогда не касался БД, и многие из них включают EF.

Что касается содержания заголовка этого раздела, то для EF 4 есть изменение. Теперь возможно иметь полностью игнорирующие постоянство типы сущностей, если это помогает вашему дизайну. Однако из самой ранней версии Entity Framework на словах вы смогли проецировать на POCO. Так что постоянное невежество всегда было доступно при необходимости. Наличие постоянного невежества для самих типов сущностей позволяет отслеживать изменения с постоянным невежественным объектом. Это может быть полезно в некоторых случаях. Но это значительно меньший набор дел, чем фиктивные заявления о модульном тестировании, что значительно снижает влияние того, что в документе делается.

ЧРЕЗВЫЧАЙНЫЕ СЛИЯНИЯ MERGE С УПРАВЛЕНИЕМ ИСТОЧНИКАМИ В СРЕДАХ КОМАНД:

Действительно ли объединение XML так сложно? Если это так, возможно, следует искать новый инструмент слияния. Я не нахожу это проблематичным.

Однако здесь есть реальная проблема, хотя, опять же, она намного более узкая, чем утверждается в документе. Вместо того, чтобы повторяться, я просто укажу вам на мой пост на эту тему .

В EF 4 можно использовать модели с первым кодом, а не модели XML, чтобы разбить модель на множество разных файлов.

8 голосов
/ 08 марта 2010

Entity Framework улучшился с версии 1, и в этом сообщении в блоге от участника NHibernate сравниваются NHibernate и Entity Framework 4.0.

5 голосов
/ 17 марта 2011

РЕДАКТИРОВАТЬ: ЭТО ИСПОЛЬЗУЕТСЯ ИСТИНА, НО ЭТОГО БОЛЬШЕ.

Как человек, который использовал Entity Framework и NHibernate ... Я настоятельно рекомендую NHibernate. Обычно, если присутствуют FOSS и MS-технология, я предлагаю MS-технологию, но я категорически не согласен с этим для EF. Я использую EF4 на ежедневной основе на работе, и мы должны создать много обходных путей из-за EF. Два года назад я использовал EF около года, а затем поменял компанию, и я работал с EF в течение прошлого года. NHibernate 2 года назад опережает EF4.

Вот пункты, которые они подняли.

Чрезмерные конфликты слияний с контролем источников в командных средах:

Это было частично исправлено, насколько я слышал. Они переместили данные позиции для дизайнера в конец .edmx, так что это больше не ужасная проблема, но все же раздражает. Если и я, и коллега одновременно попытаются изменить .edmx, мы получим ужасные конфликты слияния, потому что вся нижняя часть файла используется для хранения данных положения таблиц в конструкторе. Наш способ решения этой проблемы - использовать блокировку файлов SVN, чтобы мы не редактировали ее дважды. Или я игнорирую блокировку, и если я получаю конфликт слияния, я просто принимаю их изменения и повторяю свою работу. Большинство моих изменений не настолько велики, что они занимают много времени. Если бы это была единственная проблема, я бы с этим смирился.

Если вы используете первый код (в EF 4.1), это не проблема.

Избыточный код, необходимый для устранения отсутствия отложенной загрузки:

Добавлена ​​ленивая загрузка в 4.0.

Но загрузка по-прежнему преформ, как кусок мусора. Стремительная загрузка идет медленно, что является обычной оптимизацией, когда вам нужно ускорить ваш код. Я сталкиваюсь со случаями, когда мне приходится делать 10 000+ звонков в базу данных, когда я предпочитаю использовать готовую загрузку. Мы рассчитали время, и во многих случаях быстрее сделать несколько вызовов базы данных (делая myobject.TablenameReference.Load() в цикле) в локальную базу данных, чем использовать .Include("Tablename"). Да, я знаю, что это очень нелогично, но цифры не лгут. Кроме того, нет способа указать выборку stragety, поэтому вы не можете указать Join-fetch или нет. Так что я бы сказал, что он улучшился, но не так хорошо, как NHibernate.

Сосредоточение внимания на аспекте данных сущностей ведет к ухудшению архитектуры сущностей:

Да, это все так же верно. Опять же, хороший пример - порядок. Статус. Нам бы очень хотелось, чтобы это было перечисление, но из-за того, как спроектирован EF, у нас нет другого выбора, кроме как сделать его строкой. Они могут решить проблему перечисления в будущем, но отсутствие контроля между тем, как выполняется сопоставление между таблицей и объектом, является настоящей жалобой. NHibernate позволяет вам указать методы для выполнения сопоставлений, чтобы справиться с этим делом.

Чтобы расширить точку зрения на ответ Крэйга Стунца, EF разработан, если вы хотите взять модель данных и выбрать непосредственно из нее. (IE myModel.Orders.Where(order => order.Status == "NEW").Select(order => order.Customer.FirstName, order=> order.Customer.LastName).) В конечном итоге модель EF очень сложна для написания автоматических тестов, если вы не хотите использовать БД. Если вам нужен репозиторий, в котором вы запрашиваете объект, отвечающий некоторым критериям, и он возвращает весь объект, то именно в этом NHibernate работает лучше. (IE var order = myOrderRepository.GetByStatus(OrderStatus.New)).

Другая проблема, с которой я столкнулся в EF, - это полное отсутствие расширяемости. У нас есть одна проблема - у нас есть Enums для статуса заказа. Но если мы сделаем myModel.Orders.Where(order => order.Status == OrderStatus.New.ToString()), EF завершится сбоем в этом запросе, потому что он не знает метод .ToString (). Это сильно ухудшает наш код, потому что мы не можем добавить поддержку для этого. Также есть много внутренних методов, поэтому нам нужно вызвать странное поведение, мы не можем этого сделать.

Если вы используете NHibernate, Linq добавляет в nhibernate множество функций, которые делают его намного лучше. Используя модель, основанную на соглашениях, для большинства ваших отображений требуется очень мало кода. Если вы используете существующую базу данных, Nhibernate позволяет вам указать нестандартные соглашения для использования, а затем сопоставить их, и все легко управляется. EF 4.0 (и я не думаю, что 4.1) не поддерживает ничего подобного.

Надеюсь, это поможет вам.

0 голосов
/ 09 марта 2010

В EF 2 ленивая загрузка, http://microsoftpdc.com/Sessions/FT10?type=wmvhigh

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...