Почему NHibernate удаляет ссылочные объекты один за другим, не используя внешний ключ? - PullRequest
5 голосов
/ 30 июля 2011

У меня есть простое Parent - Child отношение, Parent имеет много Child объектов, отношение является однонаправленным:

public class Parent
{
    public virtual int Id { get; protected set; }
    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; }
}

Отображение для отношения устанавливает каскад на AllDeleteOrphan наудалить Child объекты, на которые больше не ссылается Parent:

HasMany(x => x.Children).Cascade.AllDeleteOrphan();

И теперь я очищаю список Child объектов:

var parent = session.Get<Parent>(1);
parent.Children.Clear();
session.Update(parent);

NHibernate удаляет Child объект, как и ожидалось, но он делает это, отправляя отдельный запрос DELETE для каждого Child из коллекции: DELETE FROM Child WHERE Id = ... - это может означать действительно МНОГО запросов.

В любом случае, это может быть легко сделать с помощью одного запроса как DELETE FROM Child WHERE ParentId = 1.Почему NHibernate не использует родительский внешний ключ для очистки коллекции?Кажется, он знает все, чтобы подготовить такой запрос (какой внешний ключ, какое значение и т. Д.)?

Ответы [ 2 ]

2 голосов
/ 30 июля 2011

NHibernate может и будет делать это в некоторых случаях.

Это все объяснено здесь .

0 голосов
/ 15 мая 2012

NHibernate выдает NHibernate: UPDATE "Child" SET Parent_id = null WHERE Parent_id = @p0;@p0 = 1 перед удалением потомков. Так как имеет много, не является обратным, родитель должен сбросить ассоциацию, а затем каскадно удаляет дочерний объект, потому что у ребенка могут быть установлены другие каскады, которые должны быть удалены.

Однако даже при обратном удалении одного выстрела не работает. Кажется, что NH удаляет только сразу с коллекциями элементов / компонентов.

Одной из причин может быть то, что дочерние элементы могут иметь определенные пользователем sqldeletes, дополнительные каскадные свойства и так далее. Самый простой способ для NH - это просто каскадно удалять каждого ребенка по отдельности.

...