2014-10-14 14 views
36

Mam swój podstawowy projekt w języku C#.Entity Framework 6: audyt/zmiany ścieżek

Pracuję w bazie danych, w której niektóre tabele mają kolumny "user_mod" i "date_mod", aby podpisać, kto i kiedy zrobił kilka modów i to samo z "data_new" i "user_new".

Moje pytanie: czy istnieje sposób na scentralizowanie tego i automatyczne wstawienie tych danych, gdzie utworzę instancję dbContext?

Jeśli nie, użyję narzędzia audytu. Widziałem niektóre z nich, ale jest problem: wszystkie te wymagają kodu w moim modelu. Ale nie chcę pisać w moim modelu, ponieważ jeśli będę musiał to zmienić, stracę mody. Czy jest możliwe wykorzystanie śladu rewizyjnego dla EF6 bez zapisu w pliku (plikach) modelu? W jaki sposób?

EDIT:

Moja próba zastępują SaveChanges.

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: Mam podsumował solution here.

+1

możliwe duplikat [Entity Framework DbContext SaveChanges() OriginalValue Nieprawidłowa] (http://stackoverflow.com/ pytania/9588352/entity-framework-dbcontext-savechanges-originalvalue-incorrect). W tej dziedzinie jest znacznie więcej wysiłków. Poszukaj Entity Framework + auditing. –

+2

@GertArnold dlaczego? Nie sądzę. Co więcej, chodzi o EF4, dwie wersje starsze ode mnie. –

+0

Cóż, wybrałem losową z długiej listy trafień podczas wyszukiwania StackOverflow na ten temat. Zwykle jest to nadpisywanie 'SaveChanges', które jest takie samo w EF4.W EF6 możesz zaryzykować coś w obszarze przechwytujących drzewiastych komend, ale nie jestem pewien, gdzie to cię zaprowadzi. –

Odpowiedz

61

przypadku korzystania EF6 na DbContext można użyć ChangeTracker w SaveChanges ręcznym w kategorii dodane/zmodyfikowane podmioty niestandardowego typu, na przykład 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

Twój kod wygląda zwyczajnie, ale właśnie go wypróbowałem ... Wstawiłem nowy element do jednego z moich tabel i nie wszedł do for of dodanychEntities .. jak to działa? co mogę zrobić? –

+0

Podmioty, które chcesz śledzić/kontrolować, muszą implementować moje jednostki "IAuditedEntity" –

+0

? ale moje jednostki są zdefiniowane w modelu ... i nie chcę ręcznie modyfikować automatycznie generowanego modelu. Jak mogę to zrobić? (przepraszam za dumne pytanie) –

5

Istnieje jeden sposób, aby to zrobić: można utworzyć częściową klasę, która jest taka sama jak kontekst obiektu i zaimplementować zastąpienie metody SaveChanges. W tym zastąpieniu możesz spojrzeć na wszystkie zmiany, które zostaną przekazane do DB i przetworzyć je.

Możesz przetwarzać je w dowolny sposób, w poniższym przykładzie stworzyłem interfejs IAutoTimestampEntity zawierający datę utworzenia i datę modyfikacji. Każdy obiekt tego typu będzie automatycznie aktualizowany o czas zmiany.

Możesz użyć tej samej zasady lub możesz spojrzeć na typ każdego zmienionego obiektu w szczegółach. Podoba mi się jednak deklaratywny aspekt interfejsu. Pozwala jednoznacznie ujawnić jeden aspekt automatyzacji, zamiast pozwalać na wykonanie go w trybie cichym przez warstwę EF.

Jeśli masz DbContext zamiast ObjectContext, oddać DbContext do IObjectContextAdapter aby uzyskać dostęp do ObjectStateManager

+0

nice !! Czy można również zobaczyć, co to jest usunięcie? co to jest wstawionyAutoTimestampEntity i UpdatedAutoTimestampEntity? –

+0

WstawioneAutoTimeStampEntity i UpdatedAutoTimestampEntity są nazwami, które dałem encji w wyliczeniu, więc jest to po prostu nazywanie. – samy

+0

Jeśli chodzi o usuwanie, tutaj znajduje się wyliczenie EntityState, można zobaczyć usunięte jest obecne, a także inne stany, które można śledzić: http://msdn.microsoft.com/en-us/library/system.data.entitystate%28v= vs.110% 29.aspx – samy

15
+1

Po prostu czytając twój blog o ustawianiu tego i podoba mi się twoje podejście, nie mogę się doczekać gry z tym później. Dziękuję – Tr1stan

+2

Podoba mi się twoje podejście, ale brakuje mu jednej funkcji, tj. Transakcji. Chcę przekazać wszystko do bazy danych w ramach jednej transakcji. –

+1

Zajrzę do tego. Ponadto, prosimy o wnoszenie wkładu. Dziękuję :) –

Powiązane problemy