asp.net-coreaudit.net

Audit.NET auditing 2 different contexts to 2 different databases


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));

Solution

  • 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.