如何在同一DbContext中配置Audit.Net选择性审计?
Hey there! Let's tackle your two main questions about Audit.NET in your multi-layer EF6 setup—we'll break this down clearly so you can get your audit logging working smoothly.
1. Configuring Audit Log Storage for Composite Key Entities (Same Database)
First off, great job already updating your DbContext to inherit from AuditDbContext—that's the foundational step. Here's how to get your audit logs stored in the same database's Audit table, even with composite-key entities:
Step 1: Define Your AuditLog Entity
First, create an AuditLog entity (add it to your EDMX model or use code-first if you prefer) to store the audit records. Example:
public class AuditLog { public int Id { get; set; } // Primary key for the audit log itself public string AuditEventType { get; set; } // e.g., "Update", "Insert", "Delete" public DateTime EventDate { get; set; } public string Username { get; set; } public string EntityType { get; set; } // Name of the audited entity public string EntityCompositeKey { get; set; } // Store composite key values as a string (optional but useful) public string AuditDetails { get; set; } // JSON string with full audit event data }
Add this entity to your Focus EDMX so EF recognizes it as part of your database model.
Step 2: Configure Audit.NET to Use EF as the Output Provider
Audit.NET's Entity Framework provider lets you save logs directly to your existing database. The key thing here is: composite-key entities don't require special configuration for Audit.NET to track them—Audit.NET uses EF's change tracker metadata, so it automatically captures all primary key fields (even composite ones) from your entities.
Here's the configuration code to map audit events to your AuditLog entity:
Audit.Core.Configuration.Setup() .UseEntityFramework(ef => ef .UseDbContext<FocusEntities>() // Your AuditDbContext subclass .AuditEntity<AuditLog>(auditEvent => { // Get the EF-specific event details var efEvent = auditEvent.GetEntityFrameworkEvent(); var entityEntry = efEvent.EntityEntries.FirstOrDefault(); // Extract composite key values (if available) string compositeKey = null; if (entityEntry?.PrimaryKeyValues != null) { compositeKey = string.Join(", ", entityEntry.PrimaryKeyValues.Select(kv => $"{kv.Key}: {kv.Value}")); } return new AuditLog { AuditEventType = auditEvent.EventType, EventDate = auditEvent.EventDate, Username = auditEvent.Environment.UserName, EntityType = entityEntry?.EntityType.Name, EntityCompositeKey = compositeKey, AuditDetails = auditEvent.ToJson() // Serialize full event to JSON }; }) .IgnoreMatchedProperties()); // Ignore properties that don't match between audit event and AuditLog
Step 3: Verify Database Schema
Make sure your database has the AuditLog table created (you can generate it via EF migrations or manually based on your entity definition).
2. Where to Configure Audit.NET in Your Multi-Layer WCF Setup
Since your WCF service is the entry point for all backend operations, this is the perfect place to initialize Audit.NET—you want your configuration to run once when the service starts, so all downstream layers (business logic, data access) inherit this setup.
Recommended Configuration Location
- If your WCF service is hosted in IIS: Add the configuration code to your
Global.asax.csfile'sApplication_Startmethod:protected void Application_Start(object sender, EventArgs e) { // Initialize Audit.NET here Audit.Core.Configuration.Setup() .UseEntityFramework(ef => ef .UseDbContext<FocusEntities>() .AuditEntity<AuditLog>(auditEvent => // ... same mapping as above ... ) .IgnoreMatchedProperties()); // Other WCF startup logic } - If it's a self-hosted WCF service: Add the configuration to your service host's initialization code (e.g., before opening the host).
Key Note
Avoid initializing Audit.NET in multiple layers (like data access or business logic)—this can lead to conflicting configurations or redundant setup. Keeping it in the WCF service ensures a single, consistent configuration across your entire backend.
内容的提问来源于stack exchange,提问作者DoomerDGR8

