2

我花了一些时间阅读了一些关于审计追踪的文章和文章,但仍然无法弄清楚。首先用EF 4.2代码拦截并记录更改

我需要的是一个非常基本的审计系统,这将使我的结果,如:

  • 客户“张三”是由
  • 客户“李四”被创造“用户”“删除其他用户李四”
  • 从地址‘用户’被修改‘’
  • 客户‘其它用户‘

我’被删除’李四试图覆盖上的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人,部署应用程序后,我不会有太多的控制数据库。

我很确定我在这里错过了很简单的东西。 我感谢任何帮助。

在此先感谢。

回答

2

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

第二个问题无法用DbContext API解决。 DbContext API是ObjectContext API的简化,这种简化消除了复杂场景所需的方法。一种这样的方法是SaveChanges的超负荷版本,能够不接受改变(不改变实体的状态)。

您可以通过IObjectContextAdapterDbContext转换为ObjectContext。即使有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(); 
} 
+0

性能怎么样?在将DbContext转换为ObjectContext后保存数据不是较慢? – Saber

+0

@Saber:DbContext内部使用ObjectContext,所以不应该有任何性能影响。 –