How can one delete NHibernate objects using a criteria?

强颜欢笑 提交于 2019-11-27 16:06:15

问题


This must be a simple question. Given a criteria, how one deletes the entities satisfying the criteria?

The rationale:

HQL and NH criteria are NHibernate specific constructs and as such they are server side DAL implementation details. I do not want them to "leak" to the client side. So, our client side provides LINQ expressions for the server to process. Up until now the requests where select requests and LINQ to NHibernate dealed with them just fine.

However, there is a need to implement batch delete operation now. As usual, the client side provides a LINQ expression and the server is to delete entities satisfying the expression. Unfortunately, LINQ to NHibernate is of no help here. The most it can do is translate the given LINQ expression to NHibernate criteria.

Anyway, this is the story. I wish to stress that the client side is unaware of NHibernate at all and I like it to stay this way.

P.S.

I am using NH 2.1


回答1:


You may use the criteria to select the IDs of your elements, join them in a string and use HQL to delete them?

Something like:

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);
}

This code was not tested or compiled (in particular I'm not sure of the HQL section), but I think that you got the idea: we don't fetch the whole objects thanks to the projection, but only the indices.




回答2:


Simply put, up until 2.1.2 you cannot.

However, if you can translate the LINQ expression to HQL (or the ICriteria to HQL) then you can use the overloaded ISession.Delete() method which uses a passed HQL string.




回答3:


In your repository/dao/persistencemanager/whatever class:

public IEnumerable<T> FindAll(DetachedCriteria criteria)

        {

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

        }

and then

public void Delete(DetachedCriteria criteria)

        {

            foreach (T entity in FindAll(criteria))

            {

                Delete(entity);

            }

        }

See Davy Brion's post Data Access with NHibernate.

Edit:

As far as I know, if you want to use Criteria you need to load the objects and iterate over them to delete them. Alternatively use HQL or pass in the SQL to the session.




回答4:


I know this is an old question but for argument sake; if one uses repository pattern you can declare a delete method which does the following:

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);
}

Note the code is using expressions in order for repository interface to be generic enough so you can also implement a for example Entity Framework repository.



来源:https://stackoverflow.com/questions/1326950/how-can-one-delete-nhibernate-objects-using-a-criteria

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!