2009-05-27 4 views
1

Ich benutze NHibernate und habe eine Anforderung wo ich, wenn ich eine Zeile lösche ich nicht hart die Zeile löschen sollte stattdessen den Status zu Delted aktualisieren und einige Systemeigenschaften wie Wer gelöscht etc .Löschen einer Zeile mit benutzerdefinierten SQL-Anweisung in Nhibernate

Dafür habe ich mich entschieden, mit benutzerdefinierten SQL-Anweisung wie gehen.

<sql-delete> 
    update PPDE set SysStatusID = 2 where PPDID =? 
</sql-delete> 

in der SQL-Anweisung i sind in der Lage Bezugnahme auf nur id zu bekommen, aber wie kann ich die SysUserID den Benutzer aktualisieren, die diese Zeile delted.

Grundsätzlich wie dynamische Parameterwerte in benutzerdefinierten SQL-Anweisungen eingerichtet werden.

Jede Hilfe wird sehr geschätzt.

Antwort

0

Können Sie tun dies ein interceptor

public void OnDelete(object entity, 
         object id, 
         object[] state, 
         string[] propertyNames, 
         IType[] types) 
    { 
     // if entity is myentity 
     // update user property 
    } 
+0

Ich kann dies in Interceptor tun, aber meine Anforderung besteht nicht darin, einen Datensatz physisch zu löschen, sondern nur den Status auf Gelöscht und legen Sie die UserId auf, wer es löschte. –

+0

Ja, halten Sie die benutzerdefinierte SQL in Position, wie Sie in Ihrer Frage erwähnt haben. Aber aktualisieren Sie die Benutzer-ID im Interceptor, diese Methode sollte vor Ihrem benutzerdefinierten SQL aufgerufen werden. – Surya

0

Hibernate werden versuchen, automatisch ersetzen „?“ S mit Werten aus Ihrem Unternehmen. Wenn Sie session.Delete(entity) aufrufen, wird der Wert der Eigenschaft verwendet, die der PPDID-Spalte zugeordnet ist.

Das gesagt, ich denke, es ist eine schlechte Idee, eine benutzerdefinierte SQL-Anweisung in diesem Fall zu verwenden. IMHO wird Ihr Code schwer zu verstehen und zu pflegen sein. Wenn ein Benutzer session.Delete(entity) sieht, würde er erwarten, dass eine DELETE-Anweisung ausgeführt wird, stattdessen erhält er eine UPDATE-Anweisung. Ich würde bei einem session.Update(entity) bleiben, der vorher die richtigen Werte gesetzt hat.

+0

Vielen Dank für die Antwort. Obwohl es eine schlechte Idee ist, fand ich keine Alternative, um weiche Löschungen zu implementieren. Ich möchte nicht session.Update verwenden, da ich Geschäftsregeln in der OnDelete-Methode im Interceptor definiert habe. Wenn ich session.update verwende, werden wir nicht Rufen Sie die Methode OnDelete im Interceptor auf, in der Geschäftsregeln definiert sind. –

1

Eine Möglichkeit, um das zu tun, was Sie wollen, ist die Implementierung eines DeleteEvent-Listeners, der ausgelöst wird, wenn nhibernate beschließt, Entitäten zu löschen. Von dort aus können Sie basierend auf einer Logik (normalerweise suchen Sie nach einer Schnittstelle für die Entität) entscheiden, ob Sie die Entität hard-delete oder soft-delete löschen möchten. Und wenn Sie es weich löschen, können Sie Eigenschaften wie "IsDeleted", "DeletedAt", "DeletedBy" usw. aktualisieren.

Ein guter Blog-Post, der die obigen Details beschreibt, finden Sie unter: The NHibernate FAQ - Soft Deletes

+0

Noch besser :). – Surya

+0

Ich habe versucht, mit DeleteEventListener zu implementieren, aber ich habe ein Problem damit auch. Wenn ich einen Eintrag aus einer Tasche lösche und den Anruf bei der übergeordneten Entität abrufe, wird der gelöschte Eintrag aus der Tasche physisch gelöscht, andernfalls funktioniert es einwandfrei. –

+0

Hrm, ich habe kein visuelles Studio auf diesem Computer, um damit herumzuspielen. Aber könnte es sein, weil Sie die ISoftDeletable-Schnittstelle auf der Entität in Ihrer Tasche vermissen? –

0

Aber es gibt keinen guten Ansatz, Geschäftsregeln in einer Persistenzoperation zu haben. Ihr Unternehmen muss unabhängig von persistenten Operationen wie Löschen sein.

Verwandte Themen