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

StackOverflow https://stackoverflow.com/questions/1323427

  •  19-09-2019
  •  | 
  •  

Вопрос

Мне интересно, как можно удалить объект, имеющий только его идентификатор и тип (как в mapping), используя NHibernate 2.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));

Редактировать:

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

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

sessionFactory.GetClassMetadata(type).IdentifierPropertyName

Еще одна правка.

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

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

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

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

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

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

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

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

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

Заключение

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top