【问题标题】:Audit trail design审计线索设计
【发布时间】:2013-10-16 22:15:57
【问题描述】:

目前正在开发 ASP.Net MVC 4 应用程序。我被要求记录用户在应用程序中的所有更改。只不过是Audit Trail

这是我的控制器代码

 public ActionResult SaveBasicInfo(PatientBasicInfoViewModel basicInfoViewModel)
    {

        if (ModelState.IsValid)
        {
            var loggedInUserPersonId = ((User)Session["CurrentUser"]).PersonId;
            long tenantId = TenantContext.TenantId;
            var patient = Mapper.Map<PatientBasicInfoViewModel,
                                    Patient>(basicInfoViewModel);
            patient.TenantId = tenantId;

            if (patient.PatientId > 0)
            {
                patient.UpdatedBy = loggedInUserPersonId;
                patient.UpdatedDateTime = DateTime.Now;
                patientService.UpdatePatientDetails(patient);                  
                //Here need to do Audit Log 
                //Current User modified this fields values from `xx` to `yy` on               
            }
            else
            {
                patient.AddedBy = loggedInUserPersonId;
                patientService.AddPatient(patient);
               // Here need to Log, This user created this patient record on Date
            }


          return RedirectToAction("Details", new { id = patient.PatientId });
        }

        return RedirectToAction("Details");
    }

有人能帮我设计一个表格结构吗?它对所有组合都很灵活。

还有如何同时记录旧值和新值?

也提到了Ideas on database design for capturing audit trails,但没有得到:(

替代解决方案:为每个需要审计的表创建一个影子/历史表并使用数据库触发器。解释here

这个问题是,我怎么知道这个列的值是由这个用户从这个更改为那个的?我需要按用户显示所有历史记录并作为记录

注意: 我们没有使用实体框架,我们使用简单的存储过程和 ADO.Net 并使用 POCO 类

帮我从下面推荐的here

中选择最好的
  1. 每个被审计的表都有一个单独的“历史”表

  2. 用于跟踪更改的所有表的合并“历史”表

【问题讨论】:

  • @NevilleK,我已经提到并提出了一个问题
  • 我建议你学习一些真正的 SQL 并创建一些针对 db 的触发器,以自动触发更改日志记录
  • @Jason,写触发器会影响性能吗?经常听到trigger不好
  • @Billa 使用正确的工具来完成这项工作,就像说使用线程同步结构,例如lock,会影响性能,当然会,但是您的其他选择是什么?不要做多线程:)

标签: asp.net sql-server asp.net-mvc asp.net-mvc-4 database-design


【解决方案1】:

1- 覆盖 Context 类中的 SaveChanges 方法

2-

     public override int SaveChanges()
        {
            var autoDetectChanges = Configuration.AutoDetectChangesEnabled;

            try
            {
                Configuration.AutoDetectChangesEnabled = false;
                ChangeTracker.DetectChanges();

                foreach (var entry in ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified))
                {
                   // Save entry
// here you can get the Original Values or Current Values
entry.CurrentValues 
entry.OriginalValues
                }

                ChangeTracker.DetectChanges();

                Configuration.ValidateOnSaveEnabled = false;

                return base.SaveChanges();
            }
            finally
            {
                Configuration.AutoDetectChangesEnabled = autoDetectChanges;
            }
        }

【讨论】:

【解决方案2】:

在 Ado.NET 中

您可以使用 DataTable 来检索您的数据,

您可以使用以下方法获取数据表上已修改行的完整更改集

 DataTable ChangedDataTable= yourdataTable.GetChanges(DataRowState.Modified);

然后您可以使用 DataRowVersion 获取每个修改行的原始版本和当前版本

DataRowObject[0, DataRowVersion.Original] //by Column index
DataRowObject["ColumnName", DataRowVersion.Original] //by column name 

【讨论】:

  • 我不使用数据表。我使用 SQL Reader,读取并准备对象
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 2017-08-25
  • 2015-12-14
  • 2018-11-23
  • 2016-08-25
相关资源
最近更新 更多