Uma Trilha de Auditoria (também chamada de Log de Auditoria) é uma das maneiras mais eficazes de rastrear as ações dos usuários, fornecendo evidências de uma sequência de atividades que afetam informações, processos etc.
Usando o Entity Framework Core, podemos facilmente auditar as alterações, sobrescrevendo o método SaveChanges ().
Vamos ao que interessa
Defina a classe context e as classes de entidade que conformam seu modelo:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BloggingContext : DbContext | |
{ | |
protected override void OnConfiguring | |
(DbContextOptionsBuilder optionsBuilder) | |
{ | |
optionsBuilder.UseSqlServer( | |
"Server=localhost;Database=Blogging;User Id=sa; | |
Password=<YourStrong!Passw0rd>"); | |
} | |
public DbSet<Blog> Blogs { get; set; } | |
public DbSet<Post> Posts { get; set; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Blog | |
{ | |
public int BlogId { get; set; } | |
public string Url { get; set; } | |
public ICollection<Post> Posts { get; set; } | |
} | |
public class Post | |
{ | |
public int PostId { get; set; } | |
public string Title { get; set; } | |
public string Content { get; set; } | |
public int BlogId { get; set; } | |
public Blog Blog { get; set; } | |
} |
Agora, devemos definir uma classe context auditável e o modelo AuditTrail:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BloggingAuditableContext : BloggingContext | |
{ | |
public override int SaveChanges() | |
{ | |
ChangeTracker.Entries().Where(p => p.State == EntityState.Modified).ToList().ForEach(entry => | |
{ | |
Audit(entry); | |
}); | |
return base.SaveChanges(); | |
} | |
private void Audit(EntityEntry entry) | |
{ | |
foreach (var property in entry.Properties) | |
{ | |
if (!property.IsModified) | |
continue; | |
var auditEntry = new AuditTrail | |
{ | |
Table = entry.Entity.GetType().Name, | |
Column = property.Metadata.Name, | |
OldValue = property.OriginalValue.ToString(), | |
NewValue = property.CurrentValue.ToString(), | |
Date = DateTime.Now | |
}; | |
this.AuditTrail.Add(auditEntry); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BloggingContext : DbContext | |
{ | |
... | |
public DbSet<AuditTrail> AuditTrail { get; set; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
public class AuditTrail | |
{ | |
public long AuditTrailId { get; set; } | |
public string Table { get; set; } | |
public string Column { get; set; } | |
public string OldValue { get; set; } | |
public string NewValue { get; set; } | |
public DateTime Date { get; set; } | |
} |
Com os comandos de migração EF, criamos nossa base de dados e suas tabelas:
dotnet ef migrations add InitialCreate --context BloggingContext
dotnet ef database update --context BloggingContext
Vamos aos testes
Adicionaremos dados a nossa tabela Blog:
INSERT INTO [Blogging].[dbo].[Blogs] (Url)
VALUES ('blog.victorleonardo.com');
Agora, devemos efetuar uma atualização ao registro que acabamos de inserir, utilizando nossa classe context auditável:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
... | |
using (var auditableContext = new BloggingAuditableContext()) | |
{ | |
var blog = auditableContext.Blogs.FirstOrDefault(); | |
blog.Url = "test.victorleonardo.com"; | |
auditableContext.SaveChanges(); | |
} | |
... |
Voilà:
