У меня есть два объекта в двунаправленной связи "один ко многим":
public class Storage
{
public IList<Box> Boxes { get; set; }
}
public class Box
{
public Storage CurrentStorage { get; set; }
}
И отображение:
<class name="Storage">
<bag name="Boxes" cascade="all-delete-orphan" inverse="true">
<key column="Storage_Id" />
<one-to-many class="Box" />
</bag>
</class>
<class name="Box">
<many-to-one name="CurrentStorage" column="Storage_Id" />
</class>
A Storage
может иметь многих Boxes
, но a Box
может только принадлежать одному Storage
. Мне отобразили их так, чтобы one-many имел каскад all-delete-orphan
.
Моя проблема возникает, когда я пытаюсь изменить Поле Storage
. Принятие я уже выполнил этот код:
var storage1 = new Storage();
var storage2 = new Storage();
storage1.Boxes.Add(new Box());
Session.Create(storage1);
Session.Create(storage2);
Следующий код даст мне исключение:
// get the first and only box in the DB
var existingBox = Database.GetBox().First();
// remove the box from storage1
existingBox.CurrentStorage.Boxes.Remove(existingBox);
// add the box to storage2 after it's been removed from storage1
var storage2 = Database.GetStorage().Second();
storage2.Boxes.Add(existingBox);
Session.Flush(); // commit changes to DB
Я получаю следующее исключение:
NHibernate. ObjectDeletedException: удаленный объект был бы повторно сохранен каскадом (удалите удаленный объект из ассоциаций),
Это исключение происходит, потому что у меня есть каскадный набор к all-delete-orphan
. Первое Storage
обнаруженный, что я удалил Box
от его набора и меток это для удаления. Однако, когда я добавил его к второму Storage
(на той же сессии), это пытается сохранить поле снова и ObjectDeletedException
брошен.
Мой вопрос, как я добираюсь Box
изменить его родителя Storage
не встречаясь с этим исключением? Я знаю, что одно возможное решение состоит в том, чтобы изменить каскад на просто all
, но затем я проигрываю, способность иметь NHibernate автоматически удаляют a Box
путем простого удаления его из a Storage
и не повторно связывая его с другим. Или это единственный способ сделать это, и я должен вручную звонить Session.Delete
на поле для удаления его?