Audit.NET auditing 2 different contexts to 2 different databases

479 Views Asked by At

I have an ASP.NET Core application with 2 contexts for 2 databases (context_1 and context_2). I want to audit both contexts ,using Audit.Net, to separate databases (context_audit_1 and context_audit_2)so I will have 4 databases in total.
The problem is eventhough I am using different contexts in configuration, it is still auditing to one database. In other words, context_1 and context_2 are auditing to context_audit_1.
Please see below the configuration I am using:
Context_1

                var auditDbContextOptions = new DbContextOptionsBuilder<AuditDbContext1>()
         .UseSqlServer(_connectiongStrings.PortalConnection1)
         .Options;

            //Audit Configuration
            Audit.Core.Configuration.Setup()
                .UseEntityFramework(_ => _
                    .UseDbContext<AuditDbContext1>(auditDbContextOptions)
                    .AuditTypeMapper(t => typeof(AuditLog))
                    .AuditEntityAction<AuditLog>((ev, entry, entity) =>
                    {
                        entity.AuditData = entry.ToJson();
                        entity.Action = entry.Action;
                        entity.TableName = entry.EntityType.Name;
                        entity.AuditDate = DateTime.Now;
                        entity.UserId = _auditHelperService.GetUserId();
                        entity.TablePK = entry.PrimaryKey.First().Value.ToString();
                    })
                .IgnoreMatchedProperties(true));

Context_2

            var auditDbContextOptions = new DbContextOptionsBuilder<AuditDbContext2>()
         .UseSqlServer( _connectiongStrings.PortalConnection2)
         .Options;


            //Audit Configuration
            Audit.Core.Configuration.Setup()
                .UseEntityFramework(_ => _
                    .UseDbContext<AuditDbContext2>(auditDbContextOptions)
                    .AuditTypeMapper(t => typeof(AuditLog))
                    .AuditEntityAction<AuditLog>((ev, entry, entity) =>
                    {
                        entity.AuditData = entry.ToJson();
                        entity.TableName = entry.EntityType.Name;
                        entity.Action = entry.Action;
                        entity.AuditDate = DateTime.Now;
                        entity.UserId = _auditHelperService.GetUserId();
                        entity.TablePK = entry.PrimaryKey.First().Value.ToString();
                    })
                    // the use of .IgnoreMatchedProperties(true) to avoid the library trying to set properties automatically by matching names between the audited entities and the type AuditLog
                    .IgnoreMatchedProperties(true));
1

There are 1 best solutions below

0
On BEST ANSWER

The problem is that you can't set more than one default data provider to save the events.

So the second time the Audit.Core.Configuration.Setup().UseEntityFramework() is called, it will override the default data provider previously configured.

But you can use the override of .UseDbContext() that provides a way to set the Audit DbContext to use on a per-event basis.

So maybe you could have something like this:

Audit.Core.Configuration.Setup()
    .UseEntityFramework(_ => _
        .UseDbContext(ev => ev.GetEntityFrameworkEvent().Database == "DB1" 
            ? new AuditDbContext1(auditDbContextOptions1)
            : new AuditDbContext2(auditDbContextOptions2))
        .AuditTypeMapper(t => typeof(AuditLog))
        .AuditEntityAction<AuditLog>((ev, entry, entity) =>
        {
            entity.AuditData = entry.ToJson();
            entity.Action = entry.Action;
            entity.TableName = entry.EntityType.Name;
            entity.AuditDate = DateTime.Now;
            entity.UserId = _auditHelperService.GetUserId();
            entity.TablePK = entry.PrimaryKey.First().Value.ToString();
        })
    .IgnoreMatchedProperties(true));

This is assuming your AuditLog entity is the same on both audit contexts.