This must be a simple question. Given a criteria, how one deletes the entities satisfying the criteria?
The rationale:
HQL and NH criteria
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.
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.
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.
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.