这一定是一个简单的问题。给定一个标准,如何删除满足标准的实体?
理由:
HQL和NH标准是NHibernate特定的构造,因此它们是服务器端DAL实现细节。我不希望他们“泄漏”到客户端。因此,我们的客户端为服务器提供LINQ表达式来处理。到目前为止,请求选择请求和LINQ到NHibernate处理它们的请求就好了。
但是,现在需要实现批量删除操作。像往常一样,客户端提供LINQ表达式,服务器将删除满足表达式的实体。 不幸的是,LINQ to NHibernate在这里没有任何帮助。它能做的最多就是将给定的LINQ表达式转换为NHibernate标准。
无论如何,这就是故事。我想强调的是,客户端根本不知道NHibernate,我喜欢它保持这种状态。
P.S。
我正在使用NH 2.1
答案 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存储库。