public async Task AddTrailsAsync <T>(AuditOperation auditOperation, string user, AuditableObjects <T> auditableObjects, IEnumerable <string> namesOfPropertiesToIgnore) where T : class { if (!auditConfigurationSqlServer.Enable.Value) { return; } var trails = auditableObjects.Select(o => new AuditTrail( auditableObjects.TransactionId, auditableObjects.Timestamp, auditConfigurationSqlServer.ApplicationId, auditOperation, user, httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString(), o.Key, o.Value, namesOfPropertiesToIgnore)); var transactionBuilder = new StringBuilder(); foreach (var trail in trails) { transactionBuilder.Append($@" insert into [{auditConfigurationSqlServer.SqlServer.DatabaseName}]. [{auditConfigurationSqlServer.SqlServer.SchemaName}]. [{auditConfigurationSqlServer.SqlServer.TableName}] ( [{nameof(AuditTrail.Id)}], [{nameof(AuditTrail.TransactionId)}], [{nameof(AuditTrail.Timestamp)}], [{nameof(AuditTrail.ApplicationId)}], [{nameof(AuditTrail.Operation)}], [{nameof(AuditTrail.User)}], [{nameof(AuditTrail.Origin)}], [{nameof(AuditTrail.ObjectAssembly)}], [{nameof(AuditTrail.ObjectId)}], [{nameof(AuditTrail.ObjectSerial)}] ) values ( '{trail.Id}', '{trail.TransactionId}', '{trail.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff") }', '{trail.ApplicationId}', '{trail.Operation}', '{trail.User}', {(!string.IsNullOrWhiteSpace(trail.Origin) ? $"'{trail.Origin}'" : "NULL")}, '{trail.ObjectAssembly}', '{trail.ObjectId}', {(!string.IsNullOrWhiteSpace(trail.ObjectSerial) ? $"'{trail.ObjectSerial}'" : "NULL")} );"); } await auditContext.ExecuteWithTransactionAsync(transactionBuilder.ToString()); }