4

私はIPostUpdateEventListenerインターフェイスを使用して監査ログを更新し、古い値と新しい値を取得してから、更新された各フィールドを「監査」テーブルに格納し、そのすべてをジャイブします。うまく機能しますが、満たすのに苦労している最後の要件が 2 つあります。

  1. 更新の対象となった従業員を表示します。
  2. 更新されたフィールドの「わかりやすい」名前を表示します。

#1については、私の最初の本能は、リフレクションを使用して、特定のエンティティの「従業員」プロパティを探して取得し、それがどの従業員向けであるかを見つけることでしたが、グラフの奥深くにいくつかのオブジェクトがあると、すぐに崩壊します指定された Employee オブジェクトに自動的に戻る方法はありません。

#1を解決するためのアイデアは、すべてのオブジェクトに「親」プロパティを必要とすることから、従業員タイプを探してグラフをトラバースできるようにすること(私にとって、単純な永続性の問題のためにドメインを汚染しすぎてしまう)から、別のSQLを使用することまでに及びました。外部キーをトラバースし、事後に従業員 ID を入力するジョブ (これまでのところすべてがコードベースであるため、別の SQL ジョブを維持したくありません。その SQL ジョブは非常に厄介なものになります)。

2 番目の要件については、問題なく変更された実際のプロパティ名を取得できます。フィールドの 80% から 90% では、(適切にフォーマットされた) プロパティ名が表示されるので、Pascal の大文字と小文字に基づいて名前の間隔を空けることができます。ただし、残りのフィールドはさまざまな理由で一致しません。MvcContrib の ASP.NET MVC および Fluent HTML ビルダーを使用していますが、ビュー モデルに、フィールド名がどうあるべきかをオーバーライドする属性を持つように設定を変更したとしても (したがって、ビューのみ)、これらの属性をビュー モデルから保存されているドメイン オブジェクトに一致させる実際の方法はありません。

両方の問題に対する最終的な実用的な解決策は、別のサービスで各更新操作の後に監査ログ サービスを呼び出し、必要に応じてフィールド名と従業員情報を渡すことですが、まあ、私は明らかにそこに行きたくありません。理由。

どちらの問題のアイデアも大歓迎です。2、3 日間頭を悩ませた結果、何の役にも立ちませんでした。ほとんどの人は、古い/新しい vale の単純な録音や、レコード自体の「作成/更新」のタイムスタンプだけにとどまっているようです。

4

4 に答える 4

0

これは、些細な監査証跡よりも複雑なシナリオのように思えます。そのため、これを処理するにはアプリケーション サービスを利用することにします。

  1. そのはるかにテスト可能です。
  2. その明示的。
  3. リフレクションや共通プロパティに頼る必要はありません。

私たちのシナリオはドメインの問題であるため、あなたのシナリオよりもはるかに単純ですが、アプリケーションで監査サービスを使用します。私たちのドメインは履歴を認識しており、履歴を操作します。これは、一部のレポート フロント エンド用に作成されたものではありません。

誰 (従業員) が更新を行っているかを記録していますか、それとも従業員はある種の集計ルートですか?

于 2009-07-27T20:30:10.113 に答える
0

#1 については、次のように設計しました。 MyCommon アセンブリで宣言しました。

public interface IUserSessionStore
{
    UserSession Get();
    void Set(UserSession userSession);
}

Ninject を使用してリクエストごとに作成されます。このクラスの実装は、ASPNET MVC セッションに UserSession オブジェクトを格納するだけです。

これにより、すべてのレイヤーで IUserSessionStore を要求し、このクラスが使用する UserSession を取得して、すべてのオブジェクトに監査情報として挿入できます (以下のクラスは MyModel プロジェクトにあります)。

public class AuditUpdater : DefaultSaveOrUpdateEventListener
{
    private IUserSessionStore userSessionStore;
    public AuditUpdater(IUserSessionStore userSessionStore)
    {
        this.userSessionStore = userSessionStore;
    }

    private Guid GetUserId()
    {
        return userSessionStore.Get().UserId;
    }

    private void UpdateAuditCreate(IAuditCreate auditable)
    {
        if (auditable != null)
        {
            auditable.CreationDate = DateTime.UtcNow;
            auditable.CreatedBy = GetUserId();
        }
    }

    .......
}

したがって、これを調整して、必要な従業員情報を取得できます。

喜んで私はより多くの提案をしたいと思います!

于 2014-05-06T15:52:23.450 に答える
0

ログを作成するには、IPostInsertEventListener または IPostUpdateEventListener を使用できます。流れるような構成を使用している場合は、以下の例のように構成します。

イベントは、投稿または更新のコミットがあるときに呼び出されます。

.ExposeConfiguration(c => c.EventListeners.PostCommitInsertEventListeners = new IPostInsertEventListener[] { new AuditEventPostInsert() })
.ExposeConfiguration(c => c.EventListeners.PostCommitUpdateEventListeners = new IPostUpdateEventListener[] { new AuditEventPostUpdate() });
于 2016-05-03T22:20:49.037 に答える