2016-04-27 13 views
3

監査の目的で、行が削除される前に特定のテーブルで「UpdatedBy」列を更新する必要があります。これにより、サード・パーティの監査がトリガーされます。エンティティ・フレームワークの削除前の更新

私の現在の解決策は、私のContextクラスにカスタムSaveChangesメソッドを作成することですが、削除したエンティティに対して行った変更は無視され、生成されたSQLは単にDELETEコマンドです。

SaveChangesメソッドのエンティティのUPDATEとDELETEの両方をトリガすることはできますか?

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を生成

CSコード

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

DELETE FROM EntityTable 
WHERE Id = @01 

更新

明確にするために、別のデータベースに新しい行を作成する第三者の監査フレームワークを使用しています。 DELETEの前にUPDATEを実行する目的は、別のデータベースが削除を実行したユーザーIDを格納できるようにすることです。そのため、行は元のデータベースから削除されますが、UPDATEによってトリガーされる監査行を作成する必要があります。

+1

ただし、何かを更新してから削除すると、なぜ更新する必要がありますか? たとえばテーブル "A"で "ROW1"を更新してから "ROW1"を削除すると、物理的に "ROW1"が削除されるので、 –

+0

を更新する理由はありません。 2つのトランザクションを実行する必要があります.1つは更新するトランザクション、もう1つは削除を実行するトランザクションです。 – 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 
     } 
    } 
関連する問題