This document describes the AuditDbContext base class, which provides automatic Entity Framework auditing through inheritance. For information about alternative integration approaches, see Integration Approaches. For configuring entity and property filtering, see Configuration and Filtering. For the save changes interceptor approach available in EF Core 5.0+, see Save Changes Interceptor.
AuditDbContext is an abstract base class that extends DbContext to automatically capture and log Entity Framework operations. By inheriting from AuditDbContext instead of DbContext, your context gains automatic auditing capabilities for all Insert, Update, and Delete operations without requiring explicit instrumentation at each SaveChanges call.
This class is defined in src/Audit.EntityFramework/AuditDbContext.cs22 and is available in both the Audit.EntityFramework (EF6) and Audit.EntityFramework.Core (EF Core) packages.
To enable auditing, change your DbContext to inherit from AuditDbContext:
Before:
After:
AuditDbContext provides multiple constructors to match the base DbContext constructors:
| Constructor | EF6 | EF Core | Description |
|---|---|---|---|
AuditDbContext() | ✓ | ✓ | Parameterless constructor |
AuditDbContext(DbContextOptions) | ✗ | ✓ | EF Core options-based constructor |
AuditDbContext(string) | ✓ | ✗ | Connection string constructor (EF6) |
AuditDbContext(DbConnection, bool) | ✓ | ✗ | Existing connection constructor (EF6) |
AuditDbContext(DbCompiledModel) | ✓ | ✗ | Compiled model constructor (EF6) |
All constructors internally call _helper.SetConfig(this) to initialize configuration from attributes, local settings, and global settings.
Sources: src/Audit.EntityFramework/AuditDbContext.cs27-85 src/Audit.EntityFramework/DbContextHelper.cs43-66
Inheritance and Interface Implementation
Sources: src/Audit.EntityFramework/AuditDbContext.cs22 src/Audit.EntityFramework/IAuditDbContext.cs13-106
AuditDbContext supports multiple configuration levels with the following precedence order (highest to lowest):
[AuditDbContext] attribute on the context classAuditDbContext base typeConfiguration Precedence Flow
Sources: src/Audit.EntityFramework/DbContextHelper.cs43-66 src/Audit.EntityFramework/Configuration.cs1-142
Decorate your context class with the [AuditDbContext] attribute:
Sources: src/Audit.EntityFramework/README.md331-338
Use the global Configuration.Setup() method:
Sources: src/Audit.EntityFramework/README.md417-424 src/Audit.EntityFramework/Configuration.cs19-22
Set properties directly on the context instance:
Sources: src/Audit.EntityFramework/README.md236-246
The following table describes the key properties available on AuditDbContext:
| Property | Type | Default | Description |
|---|---|---|---|
AuditEventType | string | Context name | Event type identifier, supports {context} and {database} placeholders |
AuditDisabled | bool | false | Disables auditing for this context instance |
Mode | AuditOptionMode | OptOut | Entity tracking mode (OptOut: all tracked except ignored; OptIn: none tracked except included) |
IncludeEntityObjects | bool | false | Include full entity object graphs in audit output |
ExcludeValidationResults | bool | false | Exclude entity validation results from audit output |
ExcludeTransactionId | bool | false | Exclude transaction identifiers from audit output |
ReloadDatabaseValues | bool | false | Query database for original values before modification/deletion |
MapChangesByColumn | bool | false | Use ChangesByColumn dictionary instead of Changes list |
AuditDataProvider | IAuditDataProvider | null | Custom data provider for this context (overrides global) |
AuditScopeFactory | IAuditScopeFactory | null | Custom scope factory for this context (overrides global) |
EntitySettings | Dictionary<Type, EfEntitySettings> | null | Per-entity type configuration settings |
ExtraFields | Dictionary<string, object> | Empty | Custom fields to include in audit events |
EF6-Only Properties:
| Property | Type | Default | Description |
|---|---|---|---|
IncludeIndependantAssociations | bool | false | Include many-to-many associations without join entities (EF6 only) |
Sources: src/Audit.EntityFramework/AuditDbContext.cs87-131 src/Audit.EntityFramework/IAuditDbContext.cs14-105
AuditDbContext overrides the base SaveChanges methods to intercept and audit database operations:
SaveChanges Flow for All Platforms
Sources: src/Audit.EntityFramework/AuditDbContext.cs163-250 src/Audit.EntityFramework/DbContextHelper.cs551-633
EF Core:
EF6:
All overrides delegate to DbContextHelper methods that follow this pattern:
Sources: src/Audit.EntityFramework/AuditDbContext.cs163-250 src/Audit.EntityFramework/DbContextHelper.cs608-633
These methods provide direct access to the generated audit event:
Example usage:
Sources: src/Audit.EntityFramework/AuditDbContext.cs179-239 src/Audit.EntityFramework/README.md606-617
Adds custom fields to the audit event that will be included in the output:
These fields are stored in the ExtraFields dictionary and included in the AuditEventEntityFramework.CustomFields property.
Example:
Sources: src/Audit.EntityFramework/AuditDbContext.cs150-159 src/Audit.EntityFramework/README.md586-597 src/Audit.EntityFramework/DbContextHelper.cs384-386
AuditDbContext provides three virtual methods that can be overridden to customize audit behavior at different points in the lifecycle:
Audit Lifecycle Hook Execution
Sources: src/Audit.EntityFramework/DbContextHelper.cs140-159 src/Audit.EntityFramework/DbContextHelper.cs608-633
Called after the AuditScope is created but before the EF operation executes. Use this to:
Sources: src/Audit.EntityFramework/AuditDbContext.cs135-138 src/Audit.EntityFramework/DbContextHelper.cs406
Called after the EF operation executes and after the audit event is updated with results (PKs, FKs), but before the audit scope is saved. Use this to:
Example - Save audit in same transaction:
Sources: src/Audit.EntityFramework/AuditDbContext.cs140-143 src/Audit.EntityFramework/README.md472-500
Called after the audit scope is disposed and the audit event has been persisted. Use this to:
Sources: src/Audit.EntityFramework/AuditDbContext.cs145-148
AuditDbContext delegates all auditing logic to an internal DbContextHelper instance. This design allows the same auditing logic to be shared across AuditDbContext, AuditIdentityDbContext, and manual override implementations.
DbContextHelper Architecture
Sources: src/Audit.EntityFramework/AuditDbContext.cs24 src/Audit.EntityFramework/DbContextHelper.cs27-692
The SetConfig method merges configuration from multiple sources:
Configuration Resolution Logic
Sources: src/Audit.EntityFramework/DbContextHelper.cs43-66
When SaveChanges is called, the helper creates an audit scope with the following process:
ChangeTracker.Entries() for Added/Modified/Deleted entities{context} and {database} placeholdersSources: src/Audit.EntityFramework/DbContextHelper.cs376-408 src/Audit.EntityFramework/DbContextHelper.cs441-474
The helper captures entity changes through different code paths for EF6 and EF Core:
EF Core:
CreateAuditEvent() methodEntityEntry.Properties to enumerate propertiesGetChanges() for modified entitiesGetColumnValues() for insert/delete entitiesEF6:
CreateAuditEvent() methodDbEntityEntry.CurrentValues.PropertyNames to enumerate propertiesentry.OriginalValuesSources: src/Audit.EntityFramework/DbContextHelper.Core.cs22-57 src/Audit.EntityFramework/DbContextHelper.Net45.cs22-82
AuditDbContext implements the IAuditBypass interface to provide a way to bypass auditing when needed:
This is useful when you need to save changes without creating audit records, such as when saving audit logs themselves to avoid infinite recursion.
Sources: src/Audit.EntityFramework/AuditDbContext.cs22 src/Audit.EntityFramework/AuditDbContext.cs195-203 src/Audit.EntityFramework/AuditDbContext.cs241-249
The helper resolves the data provider with the following priority:
Data Provider Resolution Flow
Sources: src/Audit.EntityFramework/DbContextHelper.cs451-459 src/Audit.EntityFramework/DbContextHelper.cs462-474
AuditDbContext is one of three approaches for Entity Framework auditing:
| Approach | Pros | Cons | When to Use |
|---|---|---|---|
| AuditDbContext Inheritance | • Simple to implement • Automatic interception • Access to lifecycle hooks | • Requires changing base class • Not compatible with other base classes | Default choice for new projects |
| Manual SaveChanges Override | • No base class requirement • Full control over implementation | • More boilerplate code • Must implement helper calls correctly | When you can't change base class |
| AuditSaveChangesInterceptor | • No code changes to DbContext • Can be added via DI • Works with sealed contexts | • EF Core 5.0+ only • Slightly less control | EF Core 5.0+ projects with existing contexts |
Sources: src/Audit.EntityFramework/README.md70-177
AuditDbContext approach:
Manual override approach:
Sources: src/Audit.EntityFramework/README.md74-129
For applications using ASP.NET Identity, the Audit.EntityFramework.Identity package provides AuditIdentityDbContext, which extends IdentityDbContext with the same auditing capabilities:
See Identity Integration for more details.
Sources: src/Audit.EntityFramework/README.md33-37 src/Audit.EntityFramework/README.md97-101 src/Audit.EntityFramework.Identity/AuditIdentityDbContext.cs22-343
Refresh this wiki