Как удалить сущность в nhibernate, имеющую только ее идентификатор и тип? - PullRequest
16 голосов
/ 24 августа 2009

Мне интересно, как можно удалить сущность, имеющую только ее идентификатор и тип (как в сопоставлении), с помощью NHibernate 2.1?

1 Ответ

28 голосов
/ 24 августа 2009

Если вы используете отложенную загрузку, Load создает только прокси.

session.Delete(session.Load(type, id));

С NH 2.1 вы можете использовать HQL. Не уверен, как это на самом деле выглядит, но что-то вроде этого: обратите внимание, что это подлежит внедрению SQL - , если возможно, используйте вместо этого параметризованные запросы с SetParameter ()

session.Delete(string.Format("from {0} where id = {1}", type, id));

Изменить:

Для загрузки вам не нужно знать имя столбца Id.

Если вам нужно это знать, вы можете получить его по метаданным NH:

sessionFactory.GetClassMetadata(type).IdentifierPropertyName

Другое редактирование.

session.Delete() создает объект

При использовании session.Delete () NH все равно загружает объект. В начале мне это не нравилось. Тогда я понял преимущества. Если сущность является частью сложной структуры, использующей наследование, коллекции или «любые» ссылки, это на самом деле более эффективно.

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

Та же ситуация возникает, когда у вас есть набор Base с, которые являются всеми экземплярами A. При загрузке коллекции в память, NH знает, что ей не нужно удалять B -материал.

Если у сущности A есть коллекция B с, которая содержит C с (и т. Д.), Она не пытается удалить C с, когда коллекция B с пустой. Это возможно только при чтении коллекции. Это особенно важно, когда C сложен сам по себе, объединяя еще больше таблиц и т. Д.

Чем сложнее и динамичнее структура, тем эффективнее она загружает реальные данные, а не "слепо" удаляет их.

HQL У удалений есть подводные камни

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

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

Заключение

Я также пытался оптимизировать удаление с помощью NH. Я сдался в большинстве случаев, потому что NH все еще умнее, он «просто работает» и обычно достаточно быстр. Один из самых сложных алгоритмов удаления, которые я написал, - анализ определений сопоставления NH и построение операторов удаления из этого. И - не удивительно - это невозможно без чтения данных из базы данных перед удалением. (Я просто уменьшил его, чтобы загрузить только первичные ключи.)

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