Каковы наиболее распространенные ошибки и анти-паттерны, которые делают пользовательские программисты NHibernate?

28

Каковы наиболее распространенные ошибки и анти-паттерны, которые делают пользовательские программисты NHibernate? Пожалуйста, объясните, почему это плохая практика, или дайте ссылку на ресурс для дальнейшего чтения.

Например:

  • Одним из общих шаблонов для начинающих программистов NHibernate является использование идентификаторов / собственных POID вместо элементов в стиле ORM. Узнайте больше здесь ...
Дариус Кучинскас
источник
1
Вы можете найти некоторые из распространенных ошибок здесь: NHProf Alerts
1
Также здесь есть несколько ценных постов о подводных

Ответы:

34

Мои личные "часто объясняемые" проблемы:

Антишаблоны

Возиться с отделенными объектами (SaveOrUpdate или Merge плюс немного грязного кода) вместо использования DTO. Чем сложнее сущности, тем сложнее код. (Это также означает, что он довольно хорошо работает с тривиальными объектами.) Айенде также называет это « Стриппер» и объясняет проблему инкапсуляции.

Непонимание постоянного невежества и написания приложений NH, как при использовании явного SQL. Симптом этого: вызов Update после изменения объекта, недоумение, почему изменения сохраняются, даже если Update не было вызвано, недоумение, как избежать сохранения изменений.

Непонимание транзакций и единицы работы . Частые анти-паттерны: неявные транзакции, сеанс на операцию и сеанс на приложение. Еще немного чтения:

Использование событий NH для добавления логики приложения (например, отслеживание изменений в триггерах вставки и обновления)

Создайте один класс на таблицу . Некоторые люди не понимают OOD, другие не понимают реляционный дизайн.

Ошибки

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

Использование объединения в сочетании с SetMaxResult. Мои последние ответы, связанные с этой темой:

Написание самоизменяющихся объектов . Когда сущность не возвращает точно значение, которое было установлено NH, она считается грязной и обновляется в каждом сеансе. Например: замена постоянной коллекции NH в установщике свойств.

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

Может быть, больше следит.

Стефан Штайнеггер
источник
2
+1: Вы должны добавить «Не использовать шаблон единицы работы» и «Один сеанс на приложение» в свой список imho.
Сокол
@Falcon: да, наверное. Это общая проблема "непонимания транзакций". Единица работы немного покрыта постоянным невежеством. Хотя это совершенно разные понятия, они приводят к одним и тем же шаблонам.
Стефан Штайнеггер
5

« Выберите проблему N + 1 ».

Здесь вы в конечном итоге выполняете выбор для каждой сущности, которой вы хотите манипулировать (N), и выборку, чтобы получить список сущностей (+1) вместо единственного выбора всех сущностей и их атрибутов.

Шон Макмиллан
источник
1
  • Слишком много абстракций
  • Не использовать Automappings с FluentNHibernate
лукавый
источник
Первый пункт немного расплывчат, но в случае, если вы имеете в виду глупые понятия, такие как сокрытие ISession за «хранилищем» или «DAO», я согласен.
Крис
1
Второй пункт, однако, является ерундой. Есть веские причины, по которым мы часто хотим иметь детальный контроль над физической моделью данных и иметь возможность отделить ее от модели предметной области. В конце концов, это точка «М» в «ОРМ». Использование автоопределений (хотя и полезно в простых сценариях) побеждает это. Кроме того, существует также проблема интеграции устаревших схем баз данных, для которых автоматическое отображение бесполезно.
Крис
Я использую встроенные в коде соглашения на основе отображения. Это обрабатывает большой кусок дерьма, который я бы иначе повторил. Тем не менее, он по-прежнему предоставляет свободу для индивидуальной настройки объекта, которая наслоена на отображение, сгенерированное соглашением. Это супер полезно.
Сэм
1

Попытка абстрагировать это, чтобы вы могли переключиться на Entity Framework (или что-то еще) позже.

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

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

Если бы действительно существовала необходимость в переключении между NHibernate и Entity Framework, был бы активно разработанный проект для поддержки этого на GitHub (возможно, что-то похожее на CommonServiceLocator) с многочисленными участниками и запросами по запросу.

jammycakes
источник