如何使用条件删除NHibernate对象?

时间:2009-08-25 08:53:47

标签: nhibernate criteria

这一定是一个简单的问题。给定一个标准,如何删除满足标准的实体?

理由:

HQL和NH标准是NHibernate特定的构造,因此它们是服务器端DAL实现细节。我不希望他们“泄漏”到客户端。因此,我们的客户端为服务器提供LINQ表达式来处理。到目前为止,请求选择请求和LINQ到NHibernate处理它们的请求就好了。

但是,现在需要实现批量删除操作。像往常一样,客户端提供LINQ表达式,服务器将删除满足表达式的实体。 不幸的是,LINQ to NHibernate在这里没有任何帮助。它能做的最多就是将给定的LINQ表达式转换为NHibernate标准。

无论如何,这就是故事。我想强调的是,客户端根本不知道NHibernate,我喜欢它保持这种状态。

P.S。

我正在使用NH 2.1

4 个答案:

答案 0 :(得分:7)

您可以使用条件选择元素的ID,将它们连接成字符串并使用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部分),但我认为您有了这样的想法:由于投影,我们不会获取整个对象,但只有索引

答案 1 :(得分:3)

简单地说,直到2.1.2你不能。

但是,如果您可以将LINQ表达式转换为HQL(或将ICriteria转换为HQL),那么您可以使用使用传递的HQL字符串的重载ISession.Delete()方法。

答案 2 :(得分:-3)

在您的repository / 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);

            }

        }

见Davy Brion的帖子Data Access with NHibernate

修改

据我所知,如果你想使用Criteria,你需要加载对象并迭代它们以删除它们。或者使用HQL或将SQL传递给会话。

答案 3 :(得分:-5)

我知道这是一个古老的问题,但为了论证;如果使用存储库模式,您可以声明执行以下操作的删除方法:

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存储库。