Delete Cascade is not working with NHibernate

自作多情 提交于 2019-12-24 12:25:04

问题


I have a table Communication which has a reference to PersonCompany. In the mapping for PersonCompany i have defined a Cascade-Delete for this reference:

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

But when I now execute the fallowing HQL-Query:

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

with

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

I always get this SqlException:

The DELETE statement conflicted with the REFERENCE constraint "FK_PersonCompany_Communication". The conflict occurred in database "proconact", table "dbo.Communication", column 'PersonCompanyId'. The statement has been terminated.

I think, NHibernate should now delete cascade the referenced records in Communication - should'nt it?

I hope someone can help me, what I am doing wrong.


回答1:


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

  • 13.3. DML-style operations,

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

  • 9.9. Lifecyles and object graphs



回答2:


way to do is,

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

because when you use bulk updates, built in constraints is not going to work in Nhibernate. You could try to create a DB level constraint.



来源:https://stackoverflow.com/questions/24477039/delete-cascade-is-not-working-with-nhibernate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!