Как эффективно удалить все, кроме самых последних дочерних элементов родительской сущности, используя NHibernate? - PullRequest
1 голос
/ 02 октября 2009

Пожалуйста, прости меня, если я не очень хорошо объясню это. Во-первых, я использую NHibernate 2.0 с .NET 3.5. В основном у меня есть сущность "EntityA" (для простоты) с одним или несколькими дочерними элементами типа EntityB. Каждый EntityB имеет номер, указывающий, как недавно он был создан. Я хотел бы удалить все, кроме самого последнего объекта EntityB. Это является частью операции очистки.

Я изо всех сил пытаюсь найти эффективный способ сделать это. Проблема в том, что экземпляры EntityB на самом деле довольно сложны и могут иметь сотни дочерних объектов. Список EntityB на EntityA загружается лениво, и в идеале я бы хотел избежать загрузки его в память, если это возможно.

Я попытался передать HQL-запрос в Session.Delete. К сожалению, HQL, похоже, не поддерживает верхний оператор, поэтому я не могу сделать выборку, чтобы выбрать, какие из них не следует удалять.

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

Любой совет будет оценен.

[Edit] К сожалению, любой запрос должен быть HQL, а не SQL, поскольку он должен быть независимым от базы данных. [/ Edit]

Приветствия

Джеймс

Ответы [ 3 ]

1 голос
/ 02 октября 2009

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

EDIT:

Я вполне уверен, что вы можете придумать для этого SQL-запрос, независимый от базы данных, но в любом случае ... Вместо того, чтобы пытаться использовать оператор top, попробуйте использовать MAX () (при условии, что в HQL есть такая функция) идентификатор верхнего элемента, а затем структурируйте оператор удаления с условием, что идентификатор не является идентификатором MAX.

0 голосов
/ 02 октября 2009

Вы должны иметь возможность использовать HQL delete Child c where c in (:list), где list - это копия списка дочерних элементов с включенными только элементами, которые должны быть удалены. list может быть получено с помощью HQL-запроса, такого как from Child c where c.Parent = :parent - HQL-запросы, по-видимому, не подчиняются стратегии выборки сопоставления (lazy vs eager) и будут извлекать детей с нетерпением только тогда, когда им будет дана инструкция с нетерпением (так что просто не ставьте в left join fetch c.SubChildren) - и затем фильтруется для включения только удаляемых элементов.

0 голосов
/ 02 октября 2009

Если ничего другого, вы можете настроить каскады в базе данных и просто сделать

Session.CreateSQLQuery([SqlStatement]).SetParameter([ParameterStuff]).ExecuteUpdate();

Я всегда стараюсь сохранять каскады, значения по умолчанию и т. Д. В базе данных и в nhibernate для таких случаев, когда вам нужно что-то сделать напрямую с базой данных.

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