2016-04-27 63 views
3

因爲我需要在特定的錶行被刪除之前,這將引發一些第三方審覈更新一列「UpdatedBy」審計的目的。更新的實體框架之前,任何刪除

我目前的解決辦法是在我的上下文類來創建一個自定義的SaveChanges方法,但我刪除的實體的任何改變我做被忽略,生成的SQL只是一個DELETE命令。

是否有可能同時觸發的UPDATE和DELETE在SaveChanges方法的實體?

CS代碼

public partial class MyContext : DbContext 
{ 
    public int SaveChanges(int userId) 
    { 
     foreach (var entry in ChangeTracker.Entries<Auditable>()) 
     { 
      if (entry.State == EntityState.Deleted) 
      { 
       entry.Entity.UpdatedBy = userId; 
      } 
     } 

     return base.SaveChanges(); 
    } 
} 

例SQL生成

DELETE FROM EntityTable 
WHERE Id = @00 

希望的SQL

UPDATE EntityTable 
SET UpdateBy = @00 
WHERE Id = @01 

DELETE FROM EntityTable 
WHERE Id = @01 

更新

爲了澄清,我使用了第三方審計框架,它在單獨的數據庫中創建新行。在執行之前刪除更新的目的是爲了讓單獨的數據庫來存儲執行刪除的用戶ID。因此,儘管該行從原始數據庫中刪除,審計行需要創建,這是由UPDATE觸發。

+1

但如果你更新任何東西然後刪除它,那麼爲什麼需要更新? 例如在表中的「A」更新「ROW1」,然後刪除「ROW1」,所以「ROW1」將被卸下,那麼爲什麼更新 – 2016-04-27 12:12:30

+0

有沒有辦法做到這一點,在EF單個事務。您將必須執行2個事務,一個更新,然後另一個執行刪除。 – Igor

+0

如何在sql server中啓用對該表的更改跟蹤?如果你使用sql server。 – vendettamit

回答

2

實體框架不能被強制執行UPDATE以及DELETE,但我可以生成SQL來手動調用更新。並在事務中運行更改。

int SaveChangesWithDelete(int userId) 
    { 
     using (var tx= Database.BeginTransaction()) //Begin a new transaction 
     { 
      var entitiyGroups = ChangeTracker.Entries() 
       .Where(e => e.State == EntityState.Deleted && e.Entity is Auditable) 
       .Select(e => e.Entity) 
       .GroupBy(d => d.GetType(); 

      foreach (var entityGroup in entitiyGroups) //Loop through deleted entities and run a manual UPDATE 
      { 
       string query = string.Format(@" 
        UPDATE {0} SET UpdatedBy = {1} 
        WHERE Id IN ({2}) 
       ", entityGroup.Key.Name, userId, string.Join(",", entityGroup.Select(e => PrimaryKeyValue(e)))); 

       Database.ExecuteSqlCommand(query); //Execute the query - this triggers the audit framework 
      } 

      int result = SaveChanges();  //save the context changes as normal 
      tx.Commit();     //commit the transaction 
      return result;     //return the result 
     } 
    }