Как можно удалить объекты NHibernate, используя критерии? - PullRequest
13 голосов
/ 25 августа 2009

Это должен быть простой вопрос. Учитывая критерии, как удалить объекты, удовлетворяющие критериям?

Обоснование:

Критерии HQL и NH являются специфическими конструкциями NHibernate и как таковые они являются деталями реализации DAL на стороне сервера. Я не хочу, чтобы они «просачивались» на сторону клиента. Таким образом, наша клиентская часть предоставляет LINQ-выражения для обработки сервером. До сих пор запросы, в которых запросы на выборку и LINQ to NHibernate обрабатывались, просто отлично.

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

Во всяком случае, это история. Я хочу подчеркнуть, что клиентская сторона вообще не знает о NHibernate, и мне нравится, чтобы он оставался таким.

приписка

Я использую NH 2,1

Ответы [ 4 ]

7 голосов
/ 18 июня 2010

Вы можете использовать критерии для выбора идентификаторов ваших элементов, объединить их в строку и использовать HQL для их удаления?

Что-то вроде:

public void Delete(ICriteria criteria, string keyName, string tableName)
{
    criteria.setProjection(Projections.Attribute(keyName));
    IList<int> itemIds = criteria.List<int>();

    string collection = string.Join(",", Array.ConvertAll<int, string>(itemIds, Convert.ToString));

    Session.HQL(string.Format("delete from {0} where {1} in ({2})", tableName, keyName, collection);
}

Этот код не был протестирован или скомпилирован (в частности, я не уверен в разделе HQL), но я думаю, что вы поняли: мы не получаем целые объекты благодаря проекции, а только индексы .

3 голосов
/ 18 июня 2010

Проще говоря, до 2.1.2 вы не можете.

Однако, если вы можете перевести выражение LINQ в HQL (или ICriteria в HQL), вы можете использовать перегруженный метод ISession.Delete(), который использует переданную строку HQL.

0 голосов
/ 19 августа 2011

Я знаю, что это старый вопрос, но ради аргумента; если используется шаблон репозитория, вы можете объявить метод удаления, который выполняет следующие действия:

public void Delete(System.Linq.Expressions.Expression<System.Func<TEntity, bool>> predicate)
{
    var entities = _session.Query<TEntity>().Where(predicate);
    foreach (var entity in entities)
        _session.Delete(entity);
}

Обратите внимание, что код использует выражения для того, чтобы интерфейс репозитория был достаточно универсальным, чтобы вы могли также реализовать, например, хранилище Entity Framework.

0 голосов
/ 25 августа 2009

В вашем хранилище / dao / persistencemanager / независимо от класса:

public IEnumerable<T> FindAll(DetachedCriteria criteria)

        {

            return criteria.GetExecutableCriteria(Session).List<T>();

        }

, а затем

public void Delete(DetachedCriteria criteria)

        {

            foreach (T entity in FindAll(criteria))

            {

                Delete(entity);

            }

        }

См. Сообщение Дэви Брайона Доступ к данным с помощью NHibernate .

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

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

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