简体   繁体   中英

Delete Cascade is not working with NHibernate

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM