Nhibernate один ко многим удалить не работает - PullRequest
2 голосов
/ 18 апреля 2011

Привет, у меня есть один ко многим ComplianceSet -> ComplianceItem. ComplianceItem имеет один ко многим ComplianceItem -> ComplianceItemInstance.

У меня есть

ComplianceSet

HasMany(x => x.GetUserComplianceItems()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

И

ComplianceItem

HasMany(x => x.GetUserComplianceItemInstances()).Inverse().Access.CamelCaseField(Prefix.Underscore).LazyLoad().Cascade.AllDeleteOrphan();

Тогда в моем коде у меня есть

userComplianceSet.GetUserComplianceItems().FirstOrDefault(....); ... userComplianceItem.RemoveUserComplianceItemInstance(userComplianceItemInstance);

этот код возвращает

удаленный объект будет повторно сохранен каскадом (удалить удаленный объект из ассоциаций) [DecisionCritical.Core.Domain.UserComplianceSet # 12]

Теперь это очень расстраивает. Если я удаляю каскад из обеих коллекций, код возвращает успех, но БД показывает, что он ничего не делал. поле ComplianceItemInstance.ComplianceItemId все еще заполнено, и, конечно, элемент все еще там. В любом случае, я просто хочу иметь возможность удалить ребенка из коллекции, вызвать save для объекта, содержащего коллекцию, и убрать эту странную вещь. Я испробовал все способы перестановок каскада, сохранить (сохранение набора, сохранение элемента), добавить удаление в ComplianceItemInstance и т. Д. И не могу заставить это работать.

Пожалуйста, помогите

1 Ответ

1 голос
/ 03 апреля 2012

Я боролся с тем же самым.Реакция немного запоздала, но, возможно, будущие читатели выиграют.

Решение о разрешении использования нулевого ключа в качестве внешнего ключа для дочерней таблицы работает, но это может быть нежелательно с точки зрения проектирования базы данных, если ваш ребенок не можетв любом случае существует без родителя.Изменение структуры базы данных исключительно потому, что этого требует NHibernate, мне не нравится.Также было нежелательно переходить с двунаправленного на однонаправленный.Поэтому я попробовал всевозможные комбинации отображений.

Я обнаружил, что использование inverse = true решило проблему.Сначала я подумал, что это плохое поведение в NHibernate, поскольку inverse = true в основном объясняется тем, что ответственность за отношение лежит на дочерней коллекции, которую, как я думал, я уже рассмотрел, вручную обновляя дочерний и родительский элементы.Но эта ответственность больше относится к базе данных, чем к чему-либо еще.

Используя inverse = true, все еще можно удалить дочерний элемент, удалив его из родительского элемента, если у вас есть Cascade.AllDeleteOrphan в родительском элементе.На стороне карты все будет корректно обновлено.Если вы решите использовать Cascade.All, вы также должны явно удалить дочерний элемент.

Если родительский элемент не загружен, вы также можете сразу же удалить дочерний элемент, просто удалив его в текущем сеансе.Но это не работает, если родительский файл загружен, и в этом случае это приведет к каскадным проблемам повторного сохранения.

Суть для меня в том, что обратное работает.И я не нашел сценария, в котором инверсия = ложь дает мне лучшие результаты, но я мог бы вернуться к этому мнению, углубившись в NHibernate.

...