2008-08-19 20 views
15

Ich verwende NHibernate in einem Projekt und ich muss Daten überprüfen. Ich fand this article auf Codeprojekt, das die IInterceptor-Schnittstelle bespricht.Datenüberwachung in NHibernate und SqlServer

Was ist Ihre bevorzugte Art der Datenprüfung? Verwenden Sie Datenbank-Trigger? Verwenden Sie etwas, das dem ähnlich ist, was im Artikel diskutiert wird?

Antwort

14

Für NHibernate 2.0 sollten Sie auch Event Listeners betrachten. Dies sind die Evolution der IInterceptor-Schnittstelle und wir verwenden sie erfolgreich für das Auditing.

3

Ich bevorzuge den von Ihnen erwähnten CodeProject-Ansatz.

Ein Problem mit Datenbankauslösern ist, dass Sie keine andere Wahl haben, als integrierte Sicherheit zusammen mit ActiveDirectory als Zugriff auf Ihren SQL Server zu verwenden. Der Grund dafür ist, dass Ihre Verbindung die Identität des Benutzers erben sollte, der die Verbindung ausgelöst hat. Wenn Ihre Anwendung ein Konto namens "sa" oder andere Benutzerkonten verwendet, wird im Feld "Benutzer" nur "sa" angezeigt.

Dies kann überschrieben werden, indem ein benannter SQL Server-Account für jeden einzelnen Benutzer der Anwendung erstellt wird. Dies ist jedoch z. B. für Intranet-öffentliche Webanwendungen nicht praktikabel.

+1

Es gibt Abhilfen/Alternativen zu geben jedem Benutzer eine SQL-Konto oder über integrierte Auth. Sie können eine "LastUpdatedByUser" -Spalte in Ihrer zu überwachenden Tabelle erstellen und sie bei jeder Aktualisierung eines Datensatzes aus der App senden. Der Trigger kann den Wert dieser Spalte verwenden, um die Audit-Datensätze zu füllen. –

5

[EDIT]

Beitrag NH2.0 Release, schauen Sie sich bitte an den Ereignis-Listener, wie unten vorgeschlagen. Meine Antwort ist veraltet.


Der IInterceptor ist der empfohlene Weg, um alle Daten in nhibernate in einer nicht-invasiven Art und Weise zu ändern. Es ist auch nützlich für die Entschlüsselung/Verschlüsselung von Daten, ohne dass Ihr Anwendungscode dies wissen muss.

Auslöser in der Datenbank verschieben die Verantwortung für die Protokollierung (ein Anwendungsrisiko) in die DBMS-Schicht, die Ihre Protokollierungslösung effektiv mit Ihrer Datenbankplattform verbindet. Durch die Kapselung der Auditing-Mechanismen in der Persistenzschicht behalten Sie die Plattformunabhängigkeit und die Transportfähigkeit des Codes bei.

Ich verwende Interceptors in Produktionscode, um Auditing in einigen großen Systemen bereitzustellen.

+0

Was ich mit der IInterceptor-Lösung ein wenig problematisch finde, ist, dass das 'LastUpdated'-Datum zum Beispiel auf das Datum gesetzt wird, das auf der Client-Workstation eingestellt ist, und es ist nicht das Datum des DB-Servers, das verwendet wird. –

3

Ich mag den Interceptor-Ansatz, der erwähnt wird, und verwende dies für das Projekt, an dem ich gerade arbeite.

Ein offensichtlicher Nachteil, der hervorzuheben ist, besteht darin, dass dieser Ansatz nur Datenänderungen überprüft, die über Ihre Anwendung vorgenommen wurden. Jegliche direkten Datenänderungen wie Ad-hoc-SQL-Skripte, die Sie von Zeit zu Zeit ausführen müssen (dies ist immer der Fall!), Werden nicht überwacht, es sei denn, Sie erinnern sich, die Einträge der Audit-Tabelle gleichzeitig auszuführen.

2

Als einen ganz anderen Ansatz könnten Sie das Decorator-Muster mit Ihren Repositories verwenden.

Say I

public interface IRepository<EntityType> where EntityType:IAuditably 
{ 
    public void Save(EntityType entity); 
} 

Dann haben wir unsere NHibernateRepository haben würde:

public class AuditingRepository<EntityType>:IRepository<EntityType> 
{ 
    /*...*/ 
    public void Save (EntityType entity) 
    { 
     entity.LastUser = security.CurrentUser; 
     entity.LastUpdate = DateTime.UtcNow; 
     innerRepository.Save(entity) 
    } 
} 

Dann ein IoC mit:

public class NHibernateRepository<EntityType>:IRepository<EntityType> 
{ 
    /*...*/ 
    public void Save (EntityType entity) 
    { 
     session.SaveOrUpdate(entity); 
    } 
} 

Dann könnten wir einen Prüfungs Repository haben Framework (StructureMap, Castle Windsor, NInject) können Sie alles ohne den Rest Ihres Codes erstellen zu wissen, dass Auditing vor sich ging.

Natürlich, wie Sie die Elemente von kaskadierten Sammlungen Prüfung ist ein anderes Thema ganz ...

+0

Ich denke nicht, dass dies die richtige Lösung ist, wenn Sie nicht explizit das Speichern aufrufen und das Flush-Verhalten von NH irgendwie deaktivieren. I.e. Eine Änderung an einer Entität kann auch ohne Aufruf der Methode beibehalten werden! – Rashack

+0

Sie verwenden session.FlushMode = FlushMode.CommitOnly? –

+0

Wenn Sie dies funktionierten, würden Sie mit Aktualisierungen in der Datenbank fertig werden, bei denen keine Änderungen mit diesem Ansatz vorgenommen werden. –