1

我有一个表 Communication,它引用了 PersonCompany。在 PersonCompany 的映射中,我为此参考定义了 Cascade-Delete:

this.HasMany(x => x.Communications)
  .AsSet()
  .KeyColumn("PersonCompanyId")
  .Fetch.Select()
  .Inverse()
  .Cascade.Delete();

但是当我现在执行闲置的 HQL 查询时:

var sql = "delete from PersonCompany where Person.Id in (:idList) or Company.Id in (:idList)";

var query = NHibernateHelper.CurrentSession.CreateQuery(sql);
query.SetParameterList("idList", contactIdList);
query.SetTimeout(0);
query.ExecuteUpdate();

我总是得到这个 SqlException:

DELETE 语句与 REFERENCE 约束“FK_PersonCompany_Communication”冲突。冲突发生在数据库“proconact”、表“dbo.Communication”、列“PersonCompanyId”中。该语句已终止。

我认为,NHibernate 现在应该删除通信中引用的记录级联 - 不应该吗?

我希望有人可以帮助我,我做错了什么。

4

2 回答 2

1

The syntax you've used is in fact part of the

which are in fact used to BULK operation on the DB server. They use the HQL syntax, but do not cover the cascade (because they are not executed in memory, just on the DB side)

This way, we can load the objects, to be deleted... and explicitly delete them. This will trigger cascades:

//var sql = "delete from PersonCompany where Person.Id in (:idList) or Company.Id in (:idList)";
var sql = "from PersonCompany where Person.Id in (:idList) or Company.Id in (:idList)";
var query = NHibernateHelper.CurrentSession.CreateQuery(sql);
query.SetParameterList("idList", contactIdList);
query.SetTimeout(0);
//query.ExecuteUpdate();
var list = query.List<PersonCompany >();
foreach (var item in list)
{
    session.Delete(item);
}
session.Flush();

What happened is, that each and every item to be deleted, and placed in ISession. During the Delete() all the cascades were properly executed

于 2014-06-29T15:06:23.733 回答
0

方法是,

IList<PersonCompany> _pCompanies = ....; <load the required person companies>
foreach (var pc in _pCompanies)
{
_session.delete(pc);
}

因为当您使用批量更新时,内置约束在 Nhibernate 中不起作用。您可以尝试创建数据库级别约束。

于 2014-06-30T05:51:42.217 回答