Nhibernate 多对多和HQL批量删除

Nhibernate 多对多和HQL批量删除,nhibernate,hql,nhibernate-mapping,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="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>
我收到这个例外:

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?

看起来它不遵循级联。更新/删除的HQL批处理操作相对较新,并且或多或少直接转换为SQL。我相信您也必须跟踪相关表格

如果只删除单个实体,那么批量删除对您没有多大好处。为了让NHibernate真正考虑到级联,它必须加载实际的实体,而您在示例中没有这样做

我问了一个类似的问题,我得到的答案可能会引起你的兴趣


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

我建议您执行正常删除,即使用nhibernate会话和Linq,如下所示:

 foreach(var sessionProvider in Session.Linq<ServiceProviderAccount >().Where(x=>x.ServiceProvider.Id==servinceProviderId))
       Session.Delete(sessionProvider);
foreach(Session.Linq()中的var sessionProvider.Where(x=>x.ServiceProvider.Id==serviceproviderid))
删除(sessionProvider);
现在请注意,这并不是一种很糟糕的删除方式,因为它们不会立即针对dB触发,并且在提交事务之前是会话的一部分,如果映射定义正确,这应该可以处理引用完整性问题


希望这能起作用。

我没有删除任何实体。我一次删除了几个。我想要的是从[table]中生成类似于DELETE的东西,其中some_field=@someparam是的,我做了一些研究,看起来您的解决方案是唯一的。谢谢
 foreach(var sessionProvider in Session.Linq<ServiceProviderAccount >().Where(x=>x.ServiceProvider.Id==servinceProviderId))
       Session.Delete(sessionProvider);