Entity Framework Голосуйте за отсутствие доверия - применительно к .NET 4?

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

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

Неясно, сохраняются ли утверждения, сделанные в Vote of No Confidence (в .NET 4), и если они достаточно серьезны, чтобы использовать другие решения. NHibernate - зрелая альтернатива, но я не знаю, какие проблемы она приносит. Я, как правило, больше склонен к решению Ms, главным образом потому, что могу рассчитывать на интеграцию с VS и поддержку разработчиков.

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

Ответ 1

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

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

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

Чтобы обратиться к утверждениям "без уверенности" напрямую и изучить их содержание и то, что было изменено в EF 4:

ИЗМЕНИТЬ ФОКУСИРОВАННЫЙ ДАННЫЙ АСПЕКТ УЧАСТНИКОВ ВЕДУЩИХ В РАЗРАБОТАННЫЕ АРХИТЕКТУРЫ ENTITY:

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

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

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

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

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

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

ОБЩИЕ, КАНОНИЧЕСКИЕ МОДЕЛИ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ЛУЧШИЕ ПРАКТИКИ:

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

Подход, основанный на отказе от канонической модели, не был затруднен из-за отсутствия сложного инструментария по линиям 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. Возможно, ограничения других ОРМ налагают технический барьер на разделение этих обязанностей. Это нормально сгибать правила, когда технология диктует, если стоимость чистоты дизайна чрезмерна. Но я сильно одобряю подход типов объектов без поведения.

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

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

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

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

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

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

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

Ответ 2

Entity Framework улучшилась с версии 1, и этот пост в блоге от вкладчика NHibernate сравнивает NHibernate и Entity Framework 4.0.

Ответ 3

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

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

Здесь точки, которые они подняли.

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

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

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

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

Они добавили ленивую загрузку в 4.0.

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

Неправильный фокус на аспекте данных объектов приводит к ухудшению архитектуры объектов:

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

Чтобы расширить точку от ответа Craig Stuntz, 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) не поддерживает ничего подобного.

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