I'm trying to save the AuditLog
data in Entity Framework in my ASP.NET Core Web API, and I'm using SQLite as my database. I tried to override the SaveChangesAsync()
method to track them.
But the CreatedBy
and CreatedOn
values are lost every time I modify a record.
Here's the overridden version of SaveChangesAsync()
method and a sample entity:
private readonly IHttpContextAccessor _contextAccessor;
public EvaDbContext(DbContextOptions options, IHttpContextAccessor contextAccessor) : base(options)
{
_contextAccessor = contextAccessor;
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
if (!_contextAccessor.IsLoginRequeust())
{
// Grab all entity entries
var entityEntries = ChangeTracker.Entries().Where(e => e.Entity is DomainObject && (e.State == EntityState.Added || e.State == EntityState.Modified));
var userId = _contextAccessor.GetUserId();
foreach (var entityEntry in entityEntries)
{
// Add current datetime for modified state
((DomainObject)entityEntry.Entity).ModifiedOn = DateTime.Now;
((DomainObject)entityEntry.Entity).ModifiedBy = userId;
// Add current datetime for added state
if (entityEntry.State == EntityState.Added)
{
((DomainObject)entityEntry.Entity).CreatedOn = DateTime.Now;
((DomainObject)entityEntry.Entity).CreatedBy = userId;
}
}
}
return await base.SaveChangesAsync(cancellationToken);
}
I actually achieved what I was looking for but I'm not happy with the solution, here's what I did:
// Check if entry state is added mode
var isAddedState = entityEntry.State == EntityState.Added;
// Detect trackeble properties
entityEntry.Property("ModifiedOn").CurrentValue = DateTime.Now;
entityEntry.Property("ModifiedBy").CurrentValue = userId;
entityEntry.Property("CreatedOn").CurrentValue = isAddedState ? DateTime.Now : entityEntry.Property("CreatedOn").OriginalValue;
entityEntry.Property("CreatedBy").CurrentValue = isAddedState ? userId : entityEntry.Property("CreatedBy").OriginalValue;