NHibernate One-to-Many - почему он обновляет дочерний элемент с нулевым внешним ключом? - PullRequest
2 голосов
/ 10 августа 2011

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

HasMany(x => x.ChildEntities)
  .KeyColumn("ChildEntityId")
  .Table("ChildEntity")
  .Not.LazyLoad()
  .Inverse()
  .Cascade.All().AsBag();

Когда вызывается Session.Update (parent), выполняются два оператора обновления. Первый обновляет родительский объект, как и ожидалось.

update Parent set ... where ParentId = 12345

Второе обновление меня смущает ...

update ChildEntity set ParentId = null where ParentId = 12345

Почему NHibernate выпускает этот второй оператор SQL? Я понимаю, что ChildEntities не инициализирован и что NHibernate, вероятно, пытается обеспечить состояние Parent, но я не могу изменить отображение, чтобы не сделать это второе обновление. Я пробовал Merge, ленивую загрузку, различные варианты каскада и т. Д., Но безуспешно. Единственный подключенный объект в сеансе, когда он пытается зафиксировать это Parent.

Обратите внимание, что я обычно подхожу к этому, извлекая сущность с включенной отложенной загрузкой, а затем сопоставляя отсоединенный объект (DTO или сущность) с подключенной сущностью, прежде чем позволить NHibernate сохраняться в базе данных. Я хочу понять, почему вышесказанное не работает, прежде чем предложить альтернативный подход.

1 Ответ

4 голосов
/ 10 августа 2011

Это раздражало.

Быстрый поиск в источнике NHibernate для "не удалось удалить коллекцию" обнаружился в блоке, который мог выполняться только, если! IsInverse (AbstractCollectionPersister.cs).Это привлекло мое внимание, потому что код отображения явно устанавливал значение Inverse для этой коллекции.

Если значение Inverse false и коллекция пуста, NH выполняет обновление для дочерней таблицы, устанавливая внешний ключ равным нулю, а внешний ключравно родительскому идентификатору.

Fluent настроен на автоматическое сопоставление всех сущностей в данном пространстве имен.Предполагалось, что что-либо с ручным отображением будет игнорироваться автоматическим отображением.Быстрая проверка файлов hbm.xml, созданных Fluent, подтвердила, что Inverse не был установлен.Я добавил Parent в список объектов, которые были явно исключены из Auto Mapping, и все начало работать.

.IgnoreBase<Parent>()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...