Entity Framework 6: Audit/Track Changes

Entity Framework 6: audit/track changes

If using EF6's DbContext you can use ChangeTracker in SaveChanges override to find added/modified entities of custom type, for example 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();
}

EF 6 DB First Audit Logs

To achieve this, I did not use any utility as my requirements were bit different. Finally I went ahead with overriding the SaveChanges method of DbContext used by EF. Also used Newtonsoft JSON library to convert whole updated object to JSON and save it.

To get complete code, check this link - How to audit MVC app which used EF DB first approach

EF6 Change tracking

You're not overriding SaveChanges(). You're creating a new wrapper class, and creating a SaveChanges method, and then trying to call SaveChanges() of your wrapped context. That's something totally different from overriding SaveChanges(). If you read the documentation for AutoDetectChangesEnabled You will find that it says this:

Gets or sets a value indicating whether the DetectChanges() method is called automatically by methods of DbContext and related classes. The default value is true.

So what it means is that DetectChanges() gets called when you call methods of the DbContext, which is something you are not doing. You ARE calling a method of the ObjectContext, which is not part of the DbContext (DbContext inherits from it), thus calling this method wouldn't trigger a DetectChanges() call.

Implementing Audit Log / Change History with MVC & Entity Framework

IF you are using EF 4 you can subscribe to the SavingChanges event.

Since Entities is a partial class you can add additional functionality in a separate file. So create a new file named Entities and there implement the partial method OnContextCreated to hook up the event

public partial class Entities
{
partial void OnContextCreated()
{
SavingChanges += OnSavingChanges;
}

void OnSavingChanges(object sender, EventArgs e)
{

var modifiedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
foreach (var entry in modifiedEntities)
{
var modifiedProps = ObjectStateManager.GetObjectStateEntry(entry.EntityKey).GetModifiedProperties();
var currentValues = ObjectStateManager.GetObjectStateEntry(entry.EntityKey).CurrentValues;
foreach (var propName in modifiedProps)
{
var newValue = currentValues[propName];
//log changes
}
}
}
}

If you are using EF 4.1 you can go through this article to extract changes

AzureSQL and EF 6 Auditing Records

To track "what has happened in the system at any point in time" you can use a feature that is built in to Azure SQL, Temporal tables. "Temporal Tables are a new programmability feature of Azure SQL Database that allows you to track and analyze the full history of changes in your data, without the need for custom coding". See:

https://learn.microsoft.com/en-us/azure/sql-database/sql-database-temporal-tables



Related Topics



Leave a reply



Submit