2010-11-08 24 views
5

Pracuję nad projektem śladu rewizyjnego, o którym nam powiedziano.Ścieżka audytu: aplikacja internetowa

Śledź wszystkie tabele (200+) w naszej db z tabelami cienia, tak jak robi to emberacja w trybie hibernacji. Wynika z tego, że tworzymy migawkę dla każdej transakcji obejmującej CUD.

W przeszłości zaimplementowałem rozwiązania kontrolne dla zbiorów skończonych ważnych danych dla każdego z moich klientów. Do aktualnej pracy, moje pytania to:

  1. Czy ma sens kontrolowanie każdej tabeli w bazie danych?
  2. Ile wartości będzie śledzić dane takie jak Envers? Każda aplikacja będzie chciała mieć delty dla określonych punktów danych. Wyszukanie ogromnych zbiorów danych w celu wykrycia delt wydaje się nierealistyczne.
  3. Rozwiązanie typu Envers wymaga powiązania akcji CUD z transakcją, która skutecznie wyklucza wyzwalacze. Wynika to z tego, że wyzwalacze działają w swoich własnych transakcjach, a zatem dane w tabelach cieni mogą zostać zsynchronizowane w przypadku wycofywania transakcji z aplikacji. Czego tu mi brakuje?
  4. Czy ktoś sugeruje używanie DB NoSQL do śledzenia zdarzeń?

Odpowiedz

0

Jedną z opcji dla bazy danych NoSQL jest RavenDB, używając jej "versioning bundle".

Chociaż w tym momencie jest prawdopodobnie za wcześnie, niedawno wysłuchałem interesującego odcinka kodu Herdinga, gdzie talk with Eric Sink on about Veracity. Jak rozumiem, Veracity jest częściowo rozproszonym systemem kontroli wersji i częścią bazy danych NoSQL. Został zaprojektowany jako backend dla wszystkiego, od systemu kontroli kodu źródłowego po wiki. Jest rozwijany od kilku lat, ale nadal jest skuteczny na etapie przed beta (od listopada 2010).

+0

Dla prawdziwości, nie jestem pewien, czy jest to możliwe: http: //veracity-scm.com/qa/questions/545/how-to-version-database-data -with-veracity – gpasse

1

W pełni zaimplementowany i można go ulepszyć więcej. Mam nadzieję, że to może pomóc komuś:

public partial class Entity:DbContext 
    { 

     public enum AuditActions {I,U,D} 

     public override int SaveChanges() 
     { 
      ChangeTracker.DetectChanges(); 
      ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; 
      // string UserName = WindowsIdentity.GetCurrent().Name; 
      IPrincipal principal = Thread.CurrentPrincipal; 
      IIdentity identity = principal == null ? null : principal.Identity; 
      string name = identity == null ? "" : identity.Name; 

      //Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity((userName), roles); 
      List<ObjectStateEntry> objectStateEntryList = 
       ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added 
                 | EntityState.Modified 
                 | EntityState.Deleted) 
       .ToList(); 

      List<DBAudit> AuditList = new List<DBAudit>(); 

      string Audittable = string.Empty; 
      foreach (ObjectStateEntry entry in objectStateEntryList) 
      { 
       Audittable = entry.EntitySet.ToString(); 

       if (!entry.IsRelationship && Audittable!="Audit table name") 
       { 

        //sIsAuditTble =entry.EntitySet="DBAudit"? true:false; 
        switch (entry.State) 
        { 
         case EntityState.Added: 
         AuditList= LogDetails(entry, name, AuditActions.I); 
          break; 
         case EntityState.Deleted: 
         AuditList= LogDetails(entry, name, AuditActions.D); 
          break; 
         case EntityState.Modified: 
         AuditList= LogDetails(entry, name, AuditActions.U); 
          break; 

        } 
       } 
      } 



       using (var context = new ProjectTrackerEntities()) 
       { 
        for (int i = 0; i < AuditList.Count; i++) 
        { 
         context.DBAudits.Add(AuditList[i]); 
         context.SaveChanges(); 
        } 
       } 

      return base.SaveChanges(); 
     } 

     public List<DBAudit> LogDetails(ObjectStateEntry entry, string UserName, AuditActions action) 
     { 
      List<DBAudit> dbAuditList = new List<DBAudit>(); 

     if (action == AuditActions.I) 
      { 

       var keyValues = new Dictionary<string, object>(); 
       var currentValues = entry.CurrentValues; 

      // entry.Entity key = new EntityKey(); 

        DBAudit audit = new DBAudit(); 
        audit.AuditId = Guid.NewGuid().ToString(); 
        audit.RevisionStamp = DateTime.Now; 
        audit.TableName = entry.EntitySet.Name; 
        audit.UserName = UserName; 
        audit.OldData = ""; 
        audit.Actions = action.ToString(); 
        for (int i = 0; i < currentValues.FieldCount; i++) 
        { 
        audit.ChangedColumns = audit.ChangedColumns + currentValues.GetName(i); 
        audit.NewData = audit.NewData + currentValues.GetValue(i); 
        audit.ChangedColumns = audit.ChangedColumns + ", "; 
        audit.NewData = audit.NewData + ", "; 
        } 
        dbAuditList.Add(audit); 
        //LogSave(audit); 




      } 
      else if (action == AuditActions.D) 
      { 
       var keyValues = new Dictionary<string, object>(); 
       var DeletedValues = entry.OriginalValues; 

       // entry.Entity key = new EntityKey(); 


       DBAudit audit = new DBAudit(); 
       audit.AuditId = Guid.NewGuid().ToString(); 
       audit.RevisionStamp = DateTime.Now; 
       audit.TableName = entry.EntitySet.Name; 
       audit.UserName = UserName; 
       audit.NewData = ""; 

       audit.Actions = action.ToString(); 
       for (int i = 0; i < DeletedValues.FieldCount; i++) 
       { 
        audit.ChangedColumns = audit.ChangedColumns + DeletedValues.GetName(i); 
        audit.OldData = audit.OldData + DeletedValues.GetValue(i); 
        audit.ChangedColumns = audit.ChangedColumns + ", "; 
        audit.OldData = audit.OldData + ", "; 
       } 
       dbAuditList.Add(audit); 
      } 
      else 
      { 

        foreach (string propertyName in entry.GetModifiedProperties()) 
        { 
         DBAudit audit = new DBAudit(); 
         DbDataRecord original = entry.OriginalValues; 
         string oldValue = original.GetValue(original.GetOrdinal(propertyName)).ToString(); 

         CurrentValueRecord current = entry.CurrentValues; 
         string newValue = current.GetValue(current.GetOrdinal(propertyName)).ToString(); 

         audit.AuditId = Guid.NewGuid().ToString(); 
         audit.RevisionStamp = DateTime.Now; 
         audit.TableName = entry.EntitySet.Name; 
         audit.UserName = UserName; 
         audit.ChangedColumns = propertyName; 
         audit.OldData = oldValue; 
         audit.NewData = newValue; 
         audit.Actions = action.ToString(); 
         dbAuditList.Add(audit); 
         //LogSave(audit); 


        } 

      } 

     return dbAuditList; 


     } 



    } 
+0

Witaj na stronie SO, tutaj dobrze jest wyjaśnić, dlaczego używać rozwiązania, a nie tylko jak. To sprawi, że twoja odpowiedź będzie bardziej wartościowa i pomoże dalszemu czytelnikowi lepiej zrozumieć, jak to robisz. Proponuję również zapoznać się z naszym FAQ: http://stackoverflow.com/faq. – ForceMagic

Powiązane problemy