Ich habe zwei Entitäten in einer bidirektionalen Eins-zu-viele-Beziehung:Wie ändere ich das übergeordnete Element eines Kindes in NHibernate, wenn cascade delete-all-orphan ist?
public class Storage
{
public IList<Box> Boxes { get; set; }
}
public class Box
{
public Storage CurrentStorage { get; set; }
}
und die Abbildung:
<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
viele Boxes
haben kann, aber ein Box
kann nur gehören zu eine Storage
. Ich habe sie so zugeordnet, dass die Eins-zu-Viele eine Kaskade von all-delete-orphan
hat.
Mein Problem entsteht, wenn ich versuche, eine Box Storage
zu ändern. Unter der Annahme, ich lief bereits diesen Code:
var storage1 = new Storage();
var storage2 = new Storage();
storage1.Boxes.Add(new Box());
Session.Create(storage1);
Session.Create(storage2);
Der folgende Code gibt mir eine Ausnahme:
// 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
ich die folgende Ausnahme erhalten:
NHibernate.ObjectDeletedException: gelöschtes Objekt wäre erneut gespeichert durch Kaskade (gelöschtes Objekt aus Assoziationen entfernen)
Diese Ausnahme tritt auf, weil ich die Kaskade auf all-delete-orphan
eingestellt habe. Die erste Storage
erkannte, dass ich die Box
aus ihrer Sammlung entfernt und markiert sie zum Löschen. Jedoch, wenn ich es der zweiten Storage
(in der gleichen Sitzung) hinzugefügt, versucht es, die Box erneut zu speichern und die ObjectDeletedException
wird geworfen.
Meine Frage ist, wie bekomme ich die Box
, um ihre Eltern Storage
ohne diese Ausnahme zu ändern? Ich weiß, eine mögliche Lösung ist es, die Kaskade zu nur all
zu ändern, aber dann verliere ich die Fähigkeit, NHibernate automatisch löschen Box
durch einfaches Entfernen von einer Storage
und nicht neu assoziieren es mit einem anderen. Oder ist dies der einzige Weg, um es zu tun und ich muss Session.Delete
manuell auf der Box anrufen, um es zu entfernen?
Was passiert, wenn Sie die Box nie aus storage1 entfernen? Wenn Sie es nur in storage2 verschieben, wird der CurrentStorage nicht überschrieben? Ich bin nicht sicher, ob das funktioniert, wenn storage1 bereits in der Sitzung geladen ist. – dotjoe
Es funktioniert, aber bis ich meine Entitäten aktualisieren, werde ich eine Kopie der Box in beiden Speichern haben. Ich hätte lieber, dass mein Datenmodell korrekt ist, anstatt darauf zu vertrauen, dass NHib das Richtige tut, wenn ich die Entität abrufe. –
Ah ja, die verwaiste wird immer gelöscht, wenn Sie aus der Sammlung entfernen. Ich denke, in diesem Fall würden Sie tun wollen, was Sie am Ende gesagt haben, Sie würden 'cascade =" all "' löschen und eine Box löschen, indem Sie aus der Sammlung entfernen und 'session.Delete (box)' aufrufen. Ich glaube nicht, dass Sie das Beste aus beiden Welten haben können :( – dotjoe