Ответ 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 и создание исключений из него. И - не удивительно - это невозможно без чтения данных из базы данных перед удалением. (Я просто уменьшил его, чтобы загружать первичные ключи.)