Как можно удалить объект в nhibernate, имеющий только его идентификатор и тип?

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

Ответы

Ответ 1

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

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

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

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

Edit:

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

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

sessionFactory.GetClassMetadata(type).IdentifierPropertyName

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

session.Delete() создает экземпляр объекта

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

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

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

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

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

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

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

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

Заключение

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