W naszym systemie zapisujemy wszystkie zmiany dokonywane przez użytkowników. Czy Entity Framework posiada mechanizm do robienia audytu?
W naszym systemie zapisujemy wszystkie zmiany dokonywane przez użytkowników. Czy Entity Framework posiada mechanizm do robienia audytu?
Entity Framework 6.1 nie posiada gotowego mechanizmu. Trzeba napisać własny mechanizm, który odczyta informacje z obiektu ChangeTracker i zapisze je w bazie danych.
Na początek stwórzmy klasę w modelu do przechowywania informacji o zmianie:
public class Audit { public int AuditId { get; set; } public string EntityName { get; set; } public string PropertyName { get; set; } public object OldValue { get; set; } public object NewValue { get; set; } public DateTime AuditDate { get; set; } }
Następnie stwórzmy metodę, która odczyta z ChangeTrackera informacje o zmianach:
public IList<Audit> GetAudits() { IList<Audit> audits = new List<Audit>(); var entities = ChangeTracker.Entries().Where (x => x.State == EntityState.Added || x.State == EntityState.Modified || x.State == EntityState.Deleted); foreach (var entity in entities) { var entityName = entity.Entity.GetType().Name; var properties = entity.CurrentValues.PropertyNames; foreach (var property in properties) { var originalValue = entity.OriginalValues[property]; var currentValue = entity.CurrentValues[property]; if ( (originalValue != null && currentValue != null && !originalValue.Equals(currentValue)) || (originalValue == null && currentValue != null) || (originalValue != null && currentValue == null) ) { audits.Add(new Audit { EntityName = entityName, PropertyName = property, OldValue = originalValue, NewValue = currentValue, AuditDate = DateTime.Now, }); } } } return audits; }
Powyższą metodę możemy wywołać podczas zapisaniu w metodzie SaveChanges:
public class MyContext : DbContext { public MyContext() : base("name=MyContext") { } public DbSet<Audit> Audits { get; set; } public override int SaveChanges() { Audits.AddRange(GetAudits()); return base.SaveChanges(); } }
Powyższe rozwiązanie może być dobrą podstawą do zbudowania własnego mechanizmu dostosowaną do indywidualnych wymagań, na przykład zapisywanie identyfikatora zalogowanego użytkownika.