2014-06-09 35 views
3

我想在實體框架中實現可審計的數據存儲。我的意圖是在任何給定的時間點保留每個記錄狀態的歷史記錄。這要求我將所有刪除語句轉換爲更新,並將所有更新語句轉換爲更新+插入。添加額外的數據庫命令與實體框架CommandTree攔截器

我跟着TechEd 2014 EF6 soft delete session視頻瞭解攔截器的基本設置,但是我已經到了一個我不確定如何進行的地步。我有查詢,刪除和插入的有效情況,但更新是棘手的。

下面是該方法的基本結構:

public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) 
{ 
    if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace) 
    { 
     //other query interceptors 

     var updateCommand = interceptionContext.OriginalResult as DbUpdateCommandTree; 
     if (updateCommand != null) 
     { 
      //I modify the command to soft delete the current record 
      //(This is pseudo code to replace to verbose EF exp builder code) 
      var newClause = GetNewSoftDeleteClause(updateCommand); 
      interceptionContext.Result = GetUpdateCommandTree(updateCommand, newClause); 

      //Here is where I want to insert a new command into the tree 
      //and copy over the data to a new record 
     } 
    } 
} 

據我所知,一個可以修改TreeCreated方法中的當前Result,但我不能找到一種方法來插入一個新的命令進入上下文。由於攔截器似乎只處理單行操作,因此我開始認爲我想要做的事情在TreeCreated方法中是不可能的。

有沒有一種方法可以完成我想要使用攔截器而不使用數據庫觸發器?

回答

0

在這種情況下,您可以覆蓋AppicationDbContext中的savechanges()。您可以使用內置屬性ChangeTracker找出要更新的對象,然後附加需要插入的新對象。

public override int SaveChanges() 
    { 
     List<DbEntityEntry> dbEntityEntries= ChangeTracker.Entries() 
       .Where(e => e.Entity is Person && e.State == EntityState.Modified) 
       .ToList() 

     foreach(var dbEntityEntrie in dbEntityEntries) 
     { 
      var person = (Person)addedCourse.Entity; 
      var log= new Log() 
       { 
        Name=person.Name; 
       } 
      Logs.Add(log); 
     } 

     return base.SaveChanges(); 
    } 

您可以使用繼承和泛型重構此代碼。