Practical NET and Software Architecture Tips: Using EF Interceptors for Entity Tracking

Listen to this Post

Entity Framework (EF) interceptors are a powerful feature that allows developers to intercept and modify database operations. One common use case is tracking when entities are created or modified. This can be achieved using the `ChangeTracker` to check the entity state and set the appropriate fields.

For example, if you are using a `DbContext` within an HTTP request, you can pass in a `UserId` to track who made the changes. This is particularly useful for audit purposes.

You Should Know:

Here are some practical commands and code snippets to implement EF interceptors in your .NET applications:

1. Creating an Interceptor:

public class AuditInterceptor : DbCommandInterceptor
{
public override InterceptionResult<int> NonQueryExecuting(
DbCommand command, 
CommandEventData eventData, 
InterceptionResult<int> result)
{
// Add logic to modify the command or log the operation
return base.NonQueryExecuting(command, eventData, result);
}
}

2. Registering the Interceptor:

public class MyDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.AddInterceptors(new AuditInterceptor());
}
}

3. Using ChangeTracker to Set Audit Fields:

public override int SaveChanges()
{
var entries = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified);

foreach (var entry in entries)
{
if (entry.State == EntityState.Added)
{
entry.Property("CreatedDate").CurrentValue = DateTime.UtcNow;
}
entry.Property("ModifiedDate").CurrentValue = DateTime.UtcNow;
}

return base.SaveChanges();
}

4. Passing UserId in HTTP Context:

public class HttpContextUserIdProvider : IUserIdProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;

public HttpContextUserIdProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}

public string GetUserId()
{
return _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
}
}

5. Injecting UserId into Interceptor:

public class AuditInterceptor : DbCommandInterceptor
{
private readonly IUserIdProvider _userIdProvider;

public AuditInterceptor(IUserIdProvider userIdProvider)
{
_userIdProvider = userIdProvider;
}

public override InterceptionResult<int> NonQueryExecuting(
DbCommand command, 
CommandEventData eventData, 
InterceptionResult<int> result)
{
var userId = _userIdProvider.GetUserId();
// Add logic to modify the command or log the operation with userId
return base.NonQueryExecuting(command, eventData, result);
}
}

What Undercode Say:

EF interceptors are a versatile tool in the .NET ecosystem, enabling developers to inject custom logic into database operations seamlessly. Whether it’s for auditing, logging, or modifying queries, interceptors can significantly enhance the functionality of your application. However, it’s crucial to use them judiciously to avoid performance bottlenecks.

For further reading, check out the following resources:

By integrating these practices, you can ensure that your application is not only robust but also maintainable and scalable.

References:

Reported By: Milan Jovanovic – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

Join Our Cyber World:

💬 Whatsapp | 💬 TelegramFeatured Image