2

我花了一些时间阅读一些关于审计跟踪的帖子和文章,但仍然无法弄清楚这一点。

我需要的是一个非常基本的审计系统,它会给我以下结果:

  • 客户“John Doe”已被“用户”删除
  • 客户“Jane Doe”是由“其他用户”创建的
  • “John Doe”的地址被“用户”修改
  • 客户“Jane Doe”已被“其他用户”删除

我试图覆盖 dbContext 上的 SaveChanges 事件,但遇到以下问题:

public override int SaveChanges()
{

        foreach (DbEntityEntry<IAuditable> entry in ChangeTracker.Entries<IAuditable>())
        {
            if (entry.State == EntityState.Added)
            {
                // since the object was not added yet, if I write to log in here and
                // for some reason SaveChanges fail, I will end up with a fake log entry
            }
            else if (entry.State == EntityState.Modified)
            {
                // same in here
            }
        }

        return base.SaveChanges();

        // here the state for all entries have changed to Unchanged or Detached.
        // detached is probably the one that was deleted however the “Unchanged”
        // could be new or modified records.
}

我知道我可以在数据库上使用触发器来完成此操作,但我想将其保留在这里,以便我可以更好地控制它,因为我不是 SQL 人员,并且在部署应用程序后我将没有那么多控制权在分贝上。

我确定我在这里遗漏了一些非常简单的东西。我很感激任何帮助。

提前致谢。

4

1 回答 1

2

您始终可以检查上下文中是否有任何审核条目,并在调用 SaveChanges 时将其删除。它将解决您的第一个问题 - 您将始终在创建新条目之前删除以前的审核条目。

第二个问题不能用 DbContext API 解决。DbContext API 是 ObjectContext API 的简化,这种简化删除了复杂场景所需的方法。一种这样的方法是SaveChanges具有不接受更改(不更改实体状态)的能力的重载版本。

您可以DbContext通过ObjectContext. IObjectContextAdapter即使有了ObjectContext它也不会直截了当:

// If you want to have audits in transaction with records you must handle
// transactions manually
using (TransactionScope scope = new TransactionScope(...))
{
    ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;
    context.SaveChanges(SaveOptions.DetectChangesBeforeSave);

    var audits = new List<Audit>();

    // Now you must call your audit code but instead of adding audits to context
    // you must add them to list. 

    // This is the reason why you must not add changes to context. You must accept
    // old changes prior to adding your new audit records otherwise EF will perform
    // changes again. If you add your entities to context and call accept before 
    // saving them your changes will be lost
    context.AcceptAllChanges();

    // Now add all audits from list to context

    context.SaveChanges();

    // Complete the transaction
    scope.Complete(); 
}
于 2011-12-02T10:48:29.120 回答