nhibernate - 多对多和HQL批量删除

标签 nhibernate hql nhibernate-mapping

我有两个实体,在它们上定义了多对多关系。

<set name="TreasuryCodes" table="ServiceProviderAccountTreasuryCode" lazy="true" cascade="all">
  <key column="ServiceProviderAccountId" />
  <many-to-many column="TreasuryCodeId" class="TreasuryCode" />
</set>

<set name="ServiceProviderAccounts" table="ServiceProviderAccountTreasuryCode" lazy="true" inverse="true" cascade="all">
  <key column="TreasuryCodeId" />
  <many-to-many column="ServiceProviderAccountId" class="ServiceProviderAccount" />
</set>

现在我想通过ServiceProviderId删除所有ServiceProviderAccounts。我写了这段代码:

    public void DeleteAllAccount(int serviceProviderId)
    {
        const string query = "delete ServiceProviderAccount spa where spa.ServiceProvider.Id = :serviceProviderId";
        repository.Session.CreateQuery(query)
            .SetInt32("serviceProviderId", serviceProviderId)
            .ExecuteUpdate();
        repository.Session.Flush();
    }

我收到此异常:

Test method Test.ServiceRepositoryTest.DeleteAllAccountTest threw exception: 
NHibernate.Exceptions.GenericADOException: could not execute update query[SQL: delete from ServiceProviderAccount where ServiceProviderId=?] ---> System.Data.SqlClient.SqlException: The DELETE statement conflicted with the REFERENCE constraint "FKBC88A84CB684BF79". The conflict occurred in database "Test", table "dbo.ServiceProviderAccountTreasuryCode", column 'ServiceProviderAccountId'.
The statement has been terminated.

我很困惑,因为我已经在实体上定义了级联,nhibernate 不应该从 ServiceProviderAccountTreasuryCode 中删除行吗?

更新


好吧,看起来 ExecuteUpdate 没有寻找 NHibernate 级联,可能是因为它在删除实体之前没有加载实体?无论如何,还有其他方法可以从 ServiceProviderAccountTreasuryCode 表中删除,然后通过 HQL 从 ServiceProviderAccounts 中删除吗?我知道我可以在数据库上使用级联,但我想避免这种情况。我想要的是通过 HQl 从多对多关联表中删除行。是否可以?或者我应该使用普通 SQL?

最佳答案

看起来您遇到了引用完整性问题,即外来键关系,其中您要删除的 id 正在其他地方引用,而该表最终将不会引用任何内容。如果这就是您想要做的,那么您可以运行 Truncate 命令,但我不确定您为什么要这样做..

我建议您进行正常的删除,即使用 nhibernate session 和 Linq,如下所示:

 foreach(var sessionProvider in Session.Linq<ServiceProviderAccount >().Where(x=>x.ServiceProvider.Id==servinceProviderId))
       Session.Delete(sessionProvider);

现在请注意,这根本不是一个糟糕的删除方法,因为它们不会立即针对 DB 触发,并且是 session 的一部分,直到您的事务提交为止,如果定义了映射,这应该可以处理您的引用完整性问题正确。

希望这能起作用..

关于nhibernate - 多对多和HQL批量删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5129676/

相关文章:

c# - 遍历 NHibernate 实体的 IQueryable 时出现消息 "plan b"的 Antlr 异常

java - Hibernate 按查询分组

visual-studio-2008 - nHibernate 和 sqlite 映射

nhibernate - 如何从 NHibernate ISession.SaveOrUpdate 返回 id

C# NHibernate 使用数据时出现 Spring LazyInitializationException

grails - 获取Grails的最新更新记录

java - Hibernate HQL 是否支持正则表达式模式匹配?

nhibernate - 如何让 NHibernate 自动更改 "Updated"列

nhibernate - NHibernate映射未在外键引用中添加ON DELETE CASCADE选项

linq - NHibernate、NHibernate.Linq 和 FluentNHibernate? throw 错误