NHibernate使用级联执行删除。所有原因N+;1删除

NHibernate使用级联执行删除。所有原因N+;1删除,nhibernate,Nhibernate,我有两个实体密码和密码散列。Password有一组PasswordHash(这些是具有不同掩码的哈希) 当我删除一个密码时,我希望所有相关的PasswordHash也被删除 我这样做了映射: mapping.HasMany(x => x.PasswordHashes) .Cascade .All() .Inverse() .ReferencedBy(x => x.Password); D

我有两个实体密码和密码散列。Password有一组PasswordHash(这些是具有不同掩码的哈希)

当我删除一个密码时,我希望所有相关的PasswordHash也被删除

我这样做了映射:

mapping.HasMany(x => x.PasswordHashes)
            .Cascade
            .All()
            .Inverse()
            .ReferencedBy(x => x.Password);
DELETE FROM "PasswordHash" WHERE "IdPasswordHash" = :p0 (N)
我希望生成两个查询:

DELETE FROM "PasswordHash" WHERE "IdPassword" = :p0
显然

DELETE FROM "Password" WHERE "IdPassword" = :p0
相反,NHibernate生成的N+1查询如下:

mapping.HasMany(x => x.PasswordHashes)
            .Cascade
            .All()
            .Inverse()
            .ReferencedBy(x => x.Password);
DELETE FROM "PasswordHash" WHERE "IdPasswordHash" = :p0 (N)

我如何才能改变这种行为,使其更为优化

编辑:删除以下内容的代码:

session.Delete(password);
session.Flush();

根据我的研究,在当前版本的NHibernate(3.3)中,似乎不可能使用域对象上的
password.hashes.Clear()
session.delete(password)
等操作使用单个
delete
语句删除子集合。NHibernate文档中提到了,但我还没有能够将单向或双向一对多关联的反向和级联的任何组合用于这项工作

一种替代方法是使用
on delete=“cascade”
,这将禁用NHibernate中的级联功能,并由数据库强制执行级联删除。更多信息可以在nh用户谷歌小组讨论中找到

Rippo在评论部分提到的另一个选项是使用HQL。您需要两条语句,因此最好将它们包装在一个事务中,即

using (var transaction = session.BeginTransaction()
{
   session.Query("delete from PasswordHash h where h.Password = :password")
                   .SetParameter("password", password)
                   .ExecuteUpdate();
   session.Delete(password);
   transaction.Commit();
}

您能给出导致N+1删除的代码吗?我想,您可能会感兴趣:使用HQL(第一次行程)删除子项,然后再删除父项?另外,您使用的是哪家数据库供应商?顺便说一句,您提到了什么(对不起,有什么愚蠢的问题)?当它为PropertyRef更改时是否会更改某些内容?很抱歉,我忘记了这是我们的扩展方法。它只是将KeyColumn设置为适当的值。