Why NHibernate deletes referenced objects one by one, not using foreign key?
I have simple Parent
-Child
relationship, Parent
has many Child
objects, the relation is unidirectional:
public class Parent
{
public virtual int Id { get; protected se开发者_JAVA技巧t; }
public virtual string Name { get; set; }
public virtual IList<Child> Children { get; set; }
}
public class Child
{
public virtual int Id { get; protected set; }
public virtual string Name { get; set; }
}
Mapping for the relation sets cascade to AllDeleteOrphan
to remove Child
objects not referenced by Parent
any more:
HasMany(x => x.Children).Cascade.AllDeleteOrphan();
And now I'm clearing the list of Child
objects:
var parent = session.Get<Parent>(1);
parent.Children.Clear();
session.Update(parent);
NHibernate deletes the Child
object as expected, but it do this by sending separate DELETE query for each Child
from the collection: DELETE FROM Child WHERE Id = ...
- that can mean really LOT of queries.
Anyway, it can be easily done using single query like DELETE FROM Child WHERE ParentId = 1
. Why NHibernate is not using the parent foreign key to clear the collection? It seems that it knows everything to prepare such query (which foreign key, what value etc.)?
NHibernate can and will do that in certain cases.
It's all explained here.
NHibernate issues a NHibernate: UPDATE "Child" SET Parent_id = null WHERE Parent_id = @p0;@p0 = 1
before deleting the childs. Since the has many is not inverse the parent has to unset the association and then cascades the delete to the child because the chuild may have other cascades set which have to be deleted.
However even with inverse one shot deletes do not work. NH only seems to delete at once with element/component collections.
One reason can be childs could have user defined sqldeletes, additional cascaded properties and so on. The easiest way for NH is to simply cascade the delete to each child seperatly.
精彩评论