2

私は監査追跡に関するいくつかの投稿や記事を読むのに時間を費やしましたが、それでもこれを理解することはできません。

私が必要としているのは、次のような結果をもたらす非常に基本的な監査システムです。

  • 顧客「JohnDoe」は「User」によって削除されました
  • 顧客「JaneDoe」は「他のユーザー」によって作成されました
  • 「JohnDoe」からのアドレスが「User」によって変更されました
  • 顧客「JaneDoe」は「他のユーザー」によって削除されました

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が呼び出されたときにそれらを削除できます。これにより、最初の問題が解決されます。新しい監査エントリを作成する前に、常に以前の監査エントリを削除します。

2番目の問題は、DbContextAPIでは解決できません。DbContext APIは、ObjectContext APIを単純化したものであり、この単純化により、複雑なシナリオに必要なメソッドが削除されました。SaveChangesそのような方法の1つは、変更を受け入れない(エンティティの状態を変更しない)機能を備えたのオーバーロードバージョンです。

DbContextObjectContext介して変換できます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 に答える