2014-10-14 8 views
36

Ich habe mein Kernprojekt in C#.Entity Framework 6: Audit/Track-Änderungen

Ich arbeite an einer Datenbank, wo einige Tabellen die Spalten "user_mod" und "date_mod" für sign haben, wer und wann einige Mods gemacht und das gleiche mit "data_new" und "user_new".

Meine Frage: Gibt es eine Möglichkeit, dies zu zentralisieren und diese Daten automatisch einfügen, wo ich die Instanz dbContext erstellen?

Wenn nicht, werde ich ein Audit-Trail-Tool verwenden. Ich habe einige davon gesehen, aber es gibt ein Problem: all diese Dinge erfordern Code in meinem Modell. Aber ich möchte nicht in mein Modell schreiben, denn wenn ich es ändern muss, werde ich die Mods verlieren. Ist es möglich, einen Audit-Trail für EF6 zu verwenden, ohne die Modelldatei (en) zu schreiben? Wie?

EDIT:

Mein Versuch, den savechanges außer Kraft zu setzen.

public partial class PieEntities : DbContext 
{ 
    public override int SaveChanges(System.Data.Objects.SaveOptions options) 
    { 
     var timestamp = DateTime.Now; 

     EntityState es = EntityState.Added; 
     ObjectStateManager o = new ObjectStateManager(); 

     foreach (ObjectStateEntry entry in o.GetObjectStateEntries(EntityState.Added)) { 
      if (entry.Entity.GetType() == typeof(TabImpianti)) { 
       TabImpianti impianto = entry.Entity as TabImpianti; 
       impianto.DATA_INS = timestamp; 
       impianto.DATA_MOD = timestamp; 
       string u = mdlImpostazioni.p.UserName; 
       impianto.USER_INS = u; 
       impianto.USER_MOD = u; 
      } 
     } 
     return base.SaveChanges(options); 
    } 
} 

UPDATE: Ich habe die solution here zusammengefasst.

+1

möglich Duplikat [Entity Framework DbContext Savechanges() Originalvalue Falsche] (http://stackoverflow.com/ Fragen/9588352/entity-framework-dbcontext-savechanges-originalvalue-incorrect). Es gibt viel mehr Anstrengungen in diesem Bereich. Suchen Sie nach Entity Framework + Auditing. –

+2

@GertArnold warum? Ich denke nicht. Außerdem handelt es sich um EF4, zwei ältere Versionen von mir. –

+0

Nun, ich habe eine zufällige aus einer langen Liste von Treffern ausgewählt, wenn ich StackOverflow zu diesem Thema suche. Es geht normalerweise um das Überschreiben von 'SaveChanges', was in EF4 gleich ist.In EF6 kannst du etwas im Bereich der Kommando-Baum-Abfangjäger wagen, aber ich bin mir nicht sicher, wohin dich das bringen wird. –

Antwort

61

Wenn EF6 die mit DbContext Sie ChangeTracker in SaveChanges Überschreibung verwenden können hinzugefügt/geändert Einheiten von benutzerdefinierten Typ zu finden, zum Beispiel IAuditedEntity.

public interface IAuditedEntity { 
    string CreatedBy { get; set; } 
    DateTime CreatedAt { get; set; } 
    string LastModifiedBy { get; set; } 
    DateTime LastModifiedAt { get; set; } 
} 

public override int SaveChanges() { 
    var addedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>() 
    .Where(p => p.State == EntityState.Added) 
    .Select(p => p.Entity); 

    var modifiedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>() 
    .Where(p => p.State == EntityState.Modified) 
    .Select(p => p.Entity); 

    var now = DateTime.UtcNow; 

    foreach (var added in addedAuditedEntities) { 
    added.CreatedAt = now; 
    added.LastModifiedAt = now; 
    } 

    foreach (var modified in modifiedAuditedEntities) { 
    modified.LastModifiedAt = now; 
    } 

    return base.SaveChanges(); 
} 
+0

Ihr Code sieht einfach aus, aber ich habe es gerade versucht ... Ich habe ein neues Element in einer meiner Tabellen eingefügt und es ging nicht in das für addierteEntities .. wie funktioniert es? Was kann ich tun? –

+0

Entitäten, die Sie verfolgen/auditieren möchten, müssen "IAuditedEntity" –

+0

meine Entitäten implementieren? aber meine Entitäten sind im Modell definiert ... und ich möchte das automatisch generierte Modell nicht manuell modifizieren. Wie kann ich es tun? (Entschuldigen Sie die DUM-Frage) –

5

Es gibt eine Möglichkeit dies zu tun: Sie können eine Teilklasse erstellen, die denselben Namen wie Ihr Objektkontext hat, und eine Überschreibung der SaveChanges-Methode implementieren. In dieser Überschreibung können Sie sich alle Änderungen ansehen, die an die Datenbank übergeben und verarbeitet werden.

Sie können sie beliebig verarbeiten, im folgenden Beispiel habe ich eine Schnittstelle IAutoTimestampEntity erstellt, die ein Erstellungsdatum und ein Änderungsdatum enthielt. Jedes Objekt dieses Typs wird automatisch mit dem Zeitpunkt der Änderung aktualisiert.

public override int SaveChanges(System.Data.Objects.SaveOptions options) 
{ 
    var timestamp = DateTime.Now; 

    foreach (var InsertedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>()) 
    { 
     InsertedAutoTimestampEntity.CreationDate = timestamp; 
     InsertedAutoTimestampEntity.ModificationDate = timestamp; 
    } 

    foreach (var UpdatedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>()) 
    { 
     UpdatedAutoTimestampEntity.ModificationDate = timestamp; 
    } 

    return base.SaveChanges(options); 
} 

Sie können das gleiche Prinzip verwenden, oder Sie können den Typ der einzelnen geänderten Entitäten im Detail betrachten. Ich mag jedoch den deklarativen Aspekt der Schnittstelle. Sie können einen Aspekt der Automatisierung explizit anzeigen, anstatt ihn von der EF-Ebene unbeaufsichtigt zu lassen.

Wenn Sie einen DbContext anstelle eines ObjectContext haben, werfen Sie Ihre DbContext-IObjectContextAdapter, um den Zugriff auf ObjectStateManager

+0

nice !! Ist es auch möglich zu sehen, was ein Löschen ist? Was sind InsertedAutoTimestampEntity und UpdatedAutoTimestampEntity? –

+0

InsertedAutoTimeStampEntity und UpdatedAutoTimestampEntity sind die Namen, die ich den Entities in der Enumeration gegeben habe, also ist es nur Benennung. – samy

+0

In Bezug auf das Löschen, hier ist die EntityState Enum, können Sie sehen, ist vorhanden, sowie andere Zustände, die Sie verfolgen können: http://msdn.microsoft.com/en-us/library/system.data.entitystate%28v= vs.110% 29.aspx – samy

15
+1

Lies einfach deinen Blog über das Einrichten und ich mag deinen Ansatz, freue mich darauf, später damit zu spielen. Vielen Dank – Tr1stan

+2

Ich mag Ihren Ansatz, aber es fehlt ein Merkmal, d. H. Transaktion. Ich möchte alles in einer Transaktion an die Datenbank übergeben. –

+1

ich werde es untersuchen. Auch, bitte fühlen Sie sich frei zu beitragen. Danke :) –