简体   繁体   English

如何记录更新<t> (列表<t> ) 使用 Audit.net 作为多个审计记录</t></t>

[英]How to log Update<T>(IList<T>) action as multiple audit records using Audit.net

I have to update bulk records in a table.我必须更新表中的批量记录。 I did it as following.我这样做如下。

BaseRepository.cs BaseRepository.cs

    public IList<T> Update<T>(IList<T> instance) where T : class
    {
        IList<T> insertedItems = new List<T>();
        int totalCount = instance.Count;
        int count = 0;

        foreach (var item in instance)
        {
            insertedItems.Add(Update(item, count == (totalCount - 1)));
            count++;
        }

        try
        {
            context.SaveChanges();
        }
        catch (DbEntityValidationException ex)
        {
            //HandleDbEntityValidationException(ex);
        }
        //
        return insertedItems;
    }

TestMethod测试方法

    public bool TestUpdate()
    {
        try
        {
            List<Test> list = new List<Test>();
            Test test1 = new Test();
            test1.Id = 3;
            test1.Message = "test string updated 40";
            Test test2 = new Test();
            test2.Id = 4;
            list.Add(test1); list.Add(test2);
            test2.Message = "test string updated 7";
            _repository.Update<Test>(list);
            this.unitOfWork.Save();
        }
        catch (Exception ex)
        {

        }
        finally
        {
            this.unitOfWork.Dispose();
        }
        return true;
    }

Then I wanted to use Audit.net for log audits.然后想用Audit.net做日志审计。 I did as following...我做了如下...

Global.asax.cs全局.asax.cs

    Audit.Core.Configuration.DataProvider = new SqlDataProvider()
        {
            ConnectionString = "Data Source=FTD-NB-MADHARA;Initial Catalog=TestAuditTrail;User ID=sctavp_user;Password=welcome@123;MultipleActiveResultSets=true",
            Schema = "dbo",
            TableName = "Event",
            IdColumnName = "EventId",
            JsonColumnName = "JsonData",

            CustomColumns = new List<CustomColumn>()
        {
            new CustomColumn("UserName", ev=> ev.Environment.UserName.ToString()),
            new CustomColumn("MachineName", ev=> ev.Environment.MachineName.ToString()),
            new CustomColumn("DomainName", ev=> ev.Environment.DomainName.ToString()),
            new CustomColumn("ModuleName", ev => "AuditTrail"),
            new CustomColumn("CallingMethod", ev=> ev.Environment.CallingMethodName.ToString()),
            new CustomColumn("DatabaseName", ev=> ev.GetEntityFrameworkEvent().Database.ToString()),
            new CustomColumn("SchemaName", ev=> ev.GetEntityFrameworkEvent().Entries[0].Schema.ToString()),
            new CustomColumn("TableName", ev=> ev.GetEntityFrameworkEvent().Entries[0].Table.ToString()),
            new CustomColumn("Action", ev=> ev.GetEntityFrameworkEvent().Entries[0].Action.ToString()),}};

ContextChanges上下文变化

    private static DbContextHelper _helper = new DbContextHelper();
    private readonly IAuditDbContext _auditContext;

    public AuditTrailContext() : base("ApplicationDatabase")
    {
        //AuditDataProvider = new NullDataProvider();
        _auditContext = new DefaultAuditContext(this);
        _helper.SetConfig(_auditContext);
        
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Add(new DecimalPrecisionAttributeConvention());
    }

    #region without AuditDbContext
    public override int SaveChanges()
    {
        return _helper.SaveChanges(_auditContext, () => base.SaveChanges());
    }

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        return await _helper.SaveChangesAsync(_auditContext, () => base.SaveChangesAsync(cancellationToken));
    }

Result结果

JsonData field JsonData 字段

    {"EventType":"DefaultAuditContext","Environment":{"UserName":"MadharaU","MachineName":"FTD-NB-MADHARA","DomainName":"BRANDIXLK","CallingMethodName":"Rocky.AuditService.Data.EntityManager.BaseRepository.Update()","AssemblyName":"Rocky.AuditService.Data.EntityManager, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Culture":"en-US"},"StartDate":"2021-02-23T03:52:47.0005326Z","EndDate":"2021-02-23T03:52:47.0371697Z","Duration":37,"EntityFrameworkEvent":{"Database":"AuditTrail","Entries":[{"Schema":"dbo","Table":"Test","Action":"Update","PrimaryKey":{"Id":3},"Changes":[{"ColumnName":"Message","OriginalValue":"test string updated 39","NewValue":"test string updated 40"}],"ColumnValues":{"Id":3,"Message":"test string updated 40"},"Valid":true,"ValidationResults":[]},{"Schema":"dbo","Table":"Test","Action":"Update","PrimaryKey":{"Id":4},"Changes":[{"ColumnName":"Message","OriginalValue":"test string updated 6","NewValue":"test string updated 7"}],"ColumnValues":{"Id":4,"Message":"test string updated 7"},"Valid":true,"ValidationResults":[]}],"Result":2,"Success":true}}

Now my question is, I have updated two records at the same time.现在我的问题是,我同时更新了两条记录。 Audit.NET has logged both as a single record in the audit table. Audit.NET 已将两者作为单个记录记录在审计表中。 Is there any method to insert log details for these two updates separately.有什么方法可以分别为这两个更新插入日志详细信息。

You have at least two options你至少有两个选择

Use the Entity Framework Data Provider使用实体框架数据提供者

If you can map the audit log table to an Entity Framework DbContext (it could be the same DbContext you are auditing or a different one), then you could use the EntityFramework Data Provider instead of the SQL Data Provider.如果您可以将审计日志表 map 转换为 Entity Framework DbContext(它可以与您正在审计的 DbContext 相同或不同),那么您可以使用EntityFramework 数据提供程序而不是 SQL 数据提供程序。

For example, assuming you have an AuditLog table mapped to a DbContext:例如,假设您有一个映射到 DbContext 的 AuditLog 表:

public class AuditLog
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string User { get; set; }
    public string Table { get; set; }
    public string JsonData { get; set; }
}
public class LogsDbContext : DbContext
{
    public DbSet<AuditLog> AuditLogs { get; set; }
    //...
}

Then you can setup the EF data provider to log each audited entry to a record on the AuditLog table:然后您可以设置 EF 数据提供程序以将每个审核条目记录到 AuditLog 表上的记录中:

Audit.Core.Configuration.Setup()
    .UseEntityFramework(config => config
        .UseDbContext<LogsDbContext>()
        .AuditTypeMapper(_ => typeof(AuditLog))
        .AuditEntityAction<AuditLog>((ev, entry, auditLog) =>
        {
            auditLog.Date = DateTime.UtcNow;
            auditLog.Table = entry.Table;
            auditLog.User = ev.Environment.UserName;
            auditLog.JsonData = entry.ToJson();
        })
        .IgnoreMatchedProperties(true));

Use a custom SQL Data Provider使用自定义 SQL 数据提供程序

Inherit from SqlDataProvider, override the Insert/InsertAsync to trigger the save for each entity entry:继承自 SqlDataProvider,覆盖 Insert/InsertAsync 以触发每个实体条目的保存:

public class SingleSqlProvider : SqlDataProvider
{
    public SingleSqlProvider(Action<ISqlServerProviderConfigurator> config) : base(config) { }

    public override object InsertEvent(AuditEvent auditEvent)
    {
        var efEvent = auditEvent as AuditEventEntityFramework;
        object lastId = null;
        if (efEvent != null)
        {
            foreach (var entry in efEvent.EntityFrameworkEvent.Entries)
            {
                var clone = AuditEvent.FromJson<AuditEventEntityFramework>(auditEvent.ToJson());
                clone.EntityFrameworkEvent.Entries.Clear();
                clone.EntityFrameworkEvent.Entries.Add(entry);
                lastId = base.InsertEvent(clone);
            }
        }
        else
        {
            return base.InsertEvent(auditEvent);
        }
        return lastId;
    }

    public async override Task<object> InsertEventAsync(AuditEvent auditEvent)
    {
        // same but Async...
    }
}

Then the setup could be:那么设置可能是:

Audit.Core.Configuration.Setup()
    .UseCustomProvider(new SingleSqlProvider(config => config
        .ConnectionString("...")
        .TableName("...")));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM