Was ist der richtige Weg, um eine nhibernate-Entität von einer asp.net POST-Aktionsmethode zu aktualisieren?

8

Ich bin neu in nHibernate und versuche, den richtigen Weg zu finden, um losgelöste Objekte von einem Webanwendungsformular-POST zu aktualisieren. (Wir verwenden ASP.NET MVC)

Das Objekt, das ich zu aktualisieren versuche, enthält (unter anderem) eine IList von untergeordneten Objekten, die in etwa wie folgt abgebildet sind:

%Vor%

Wir haben unser MVC-Bearbeitungsansichtsformular so eingerichtet, dass unsere Aktionsmethode bei der Rückbuchung an ein Objekt übergeben wird (einschließlich der Liste & lt; & gt; von untergeordneten Elementen. Wir runden alle Entitäts-IDs korrekt über das Formular ab. <) / p>

Unser naive Versuch, die post-action-Methode auszuführen, macht eine Session.SaveOrUpdate (parentObject) mit dem parentObject, das vom standardmäßigen Modelbinder aus dem View-Formular gekratzt wurde.

Dies scheint für jedes der folgenden Szenarien zu funktionieren:

  • Erstellen eines neuen übergeordneten Objekts
  • Ändern der Eigenschaften des übergeordneten Elements
  • Hinzufügen neuer untergeordneter Objekte
  • Vorhandene untergeordnete Objekte ändern (Wenn ich auf nHibernate-Protokolle schaue, kann ich sehen, ob die Objekte korrekt neu sind oder existieren und das entsprechende UPDATE oder INSERT ausgeben)

Das Szenario, das fehlschlägt, ist:  - Untergeordnete Objekte löschen - wenn sie sich nicht in der IList befinden, werden sie nicht aus der Datenbank gelöscht. Es gibt keine Ausnahme oder irgendetwas, sie werden einfach nicht gelöscht.

Nach meinem Verständnis liegt das daran, dass die Magie, die nHibernate zum Erstellen einer Liste von Kindern benötigt, die gelöscht werden müssen, nicht mit getrennten Instanzen funktioniert.

Ich konnte kein einfaches Beispiel dafür finden, wie diese Art von Aktionsmethode mit nHibernate aussehen sollte (dh ein Modellbinder-Objekt als eine freistehende nHibernate-Instanz verwenden) - Beispiele basierend auf MS EF (zB Ссылка ) scheint eine Methode 'ApplyPropertyChanges' zu verwenden, um geänderte Eigenschaften zu kopieren das modellgebundene Objekt zu einer erneut geladenen Entitätsinstanz.

Nach all dem ist die Frage ziemlich einfach - wenn ich den Modellbinder habe, geben Sie mir ein neues Objekt, das Sammlungen von Kindobjekten enthält, wie soll ich das über nHibernate aktualisieren (wobei 'Aktualisieren' möglicherweise das Löschen von enthält) Kinder)?

    
Will Dean 27.04.2009, 16:40
quelle

2 Antworten

4

Hier ist ein Beispiel, das das tut, was Sie meiner Meinung nach tun. Lass es mich wissen, wenn ich missverstanden habe, was du versuchst.

Angesichts der folgenden "Domain" -Klassen:

%Vor%

Mit folgender Zuordnung:

%Vor%

Dieser Test:

%Vor%

wird ausgeführt und generiert den folgenden sql:

DeletingChildrenOfEvictedObject.CanDeleteChildren: Übergeben NHibernate: INSERT IN [Person] (Name, Id) VALUES (@ p0, @ p1); @ p0 = 'joe', @ p1 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

NHibernate: INSERT IN [Pet] (Name, Id) WERTE (@ p0, @ p1); @ p0 = 'Hund', @ p1 = '464e59c7-74d0-4317-9c22-9bf801013abb'

NHibernate: INSERT IN [Pet] (Name, Id) WERTE (@ p0, @ p1); @ p0 = 'Katze', @ p1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'

NHibernate: UPDATE [Haustier] SET Person_id = @ p0 WHERE Id = @ p1; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2', @ p1 = '464e59c7-74d0-4317-9c22-9bf801013abb'

NHibernate: UPDATE [Haustier] SET Person_id = @ p0 WHERE Id = @ p1; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2', @ p1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'

NHibernate: SELECT person0_.Id als Id5_0_, person0_.Name als Name5_0_ FROM [Person] person0_ WHERE person0_.Id=@p0; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

NHibernate: SELECT pets0_.Person_id als Person3_1_, pets0_.Id als Id1_, pets0_.Id als Id6_0_, pets0_.Name als Name6_0_ FROM [Pet] pets0_ WHERE pets0_.Person_id=@p0; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

NHibernate: UPDATE [Person] SET Name = @ p0 WHERE Id = @ p1; @ p0="Ausgeschlossen", @ p1 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

NHibernate: UPDATE [Pet] SET Name = @ p0 WHERE Id = @ p1; @ p0 = 'Hund', @ p1 = '464e59c7-74d0-4317-9c22-9bf801013abb' NHibernate: UPDATE [Haustier] SET Person_id = null WHERE Person_id = @ p0 UND Id = @ p1; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2', @ p1 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'

NHibernate: LÖSCHEN VON [Haustier] WHERE Id = @ p0; @ p0 = '010c2fd9-59c4-4e66-94fb-9bf801013abb'

NHibernate: SELECT person0_.Id als Id5_0_, person0_.Name als Name5_0_ FROM [Person] person0_ WHERE person0_.Id=@p0; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

NHibernate: SELECT pets0_.Person_id als Person3_1_, pets0_.Id als Id1_, pets0_.Id als Id6_0_, pets0_.Name als Name6_0_ FROM [Pet] pets0_ WHERE pets0_.Person_id=@p0; @ p0 = 'cd123fc8-6163-42a5-aeeb-9bf801013ab2'

Beachten Sie die DELETE FROM [Pet] ...

Sie müssen also in der Lage sein, ein Person-Objekt (in diesem Beispiel) mit den geänderten Sammlungen zu hibernieren und zu bestimmen, was gelöscht werden soll. Stellen Sie sicher, dass Sie das Attribut Cascade.AllDeleteOrphan () festgelegt haben.

    
Rob Scott 27.04.2009, 19:50
quelle
1

Robs Antwort überzeugte mich, den Ansatz "Laden Sie den vorhandenen Artikel in die neue Sitzung und dann zusammenzuführen" näher zu betrachten, und natürlich gibt es ISession.Merge, was genau das zu tun scheint, was ich wollte, nämlich a frisches Objekt und füge es mit seinem Vorgänger zusammen, der gerade in die zweite Sitzung geladen wurde.

Ich denke also, die Antwort auf die Frage, die ich zu stellen versuchte, lautet: "Laden Sie die vorhandene Entität neu und rufen Sie 'ISession.Merge' mit der neuen Entität auf."

    
Will Dean 27.04.2009 20:44
quelle

Tags und Links