2

EF 4.3.1を使用していますが、コンテキストでSaveChanges()をオーバーライドして、オブジェクトとその状態のリストを取得し、監査ログテーブルにエントリを作成できるようにしました。レコードのIDを監査ログテーブルに保存して、参照できるようにする必要があります。これは、レコードが挿入されるときに問題になります。保存する前にIDにアクセスできないためです。その時点でIDを取得する方法はありますか?

public override int SaveChanges()
{
        ChangeTracker.DetectChanges();

        var objectStateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
        var modifiedAuditableEntities = objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(e => (IAuditable)e.Entity != null);

        foreach (var entry in modifiedAuditableEntities)
        {
            var entity = (IAuditable)entry.Entity;

            if (entity != null)
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entity.IsAdded = true;
                        break;
                    case EntityState.Deleted:
                        entity.IsDeleted = true;
                        break;
                    case EntityState.Modified:
                        entity.IsModified = true;
                        break;
                }

                this.EntitySet<AuditLogEntry>().Add(this.auditLogService.CreateAuditLogEntryForEntity((IAuditable)entry.Entity));
            }
        return base.SaveChanges();
}
4

3 に答える 3

5

保存と監査ログの両方を同時に作成することが目標である場合は、メソッドをアトミ​​ックにするために、トランザクションスコープでラップすることができます。

    public override int SaveChanges()
    {
        ChangeTracker.DetectChanges();
        using (var scope = new TransactionScope())
        {
            var objectStateManager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
            var modifiedAuditableEntities =
                objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(
                    e => (IAuditable) e.Entity != null);
            var result = base.SaveChanges();
            foreach (var entry in modifiedAuditableEntities)
            {
                var entity = (IAuditable) entry.Entity;

                if (entity != null)
                {
                    switch (entry.State)
                    {
                        case EntityState.Added:
                            entity.IsAdded = true;
                            break;
                        case EntityState.Deleted:
                            entity.IsDeleted = true;
                            break;
                        case EntityState.Modified:
                            entity.IsModified = true;
                            break;
                    }

                    this.EntitySet<AuditLogEntry>().Add(
                        this.auditLogService.CreateAuditLogEntryForEntity((IAuditable) entry.Entity));
                }
            }
            base.SaveChanges();

            scope.Complete();
            return result;
        }
    }
于 2012-10-17T12:35:43.837 に答える
2

Id Idはデータベースによって生成された整数であり、変更の保存を呼び出す前に取得する方法はありません。考えられる解決策は次のとおりです。

  • トリガー
  • 主キーとしてのGUIDの使用
  • データベースによって管理されていないキー生成戦略を使用する(NHibernateのHiLo)
  • 最初にbase.SaveChanges()を呼び出してから、結果を調べます。
于 2012-10-17T12:30:27.363 に答える
1

データベースレベルでストアドプロシージャを使用して挿入/監査機能(およびその他のデータベースの変更)を実行し、ユーザーからの挿入/更新/削除のアクセス許可を取り消すことをお勧めします。そのため、更新プロセスと監査テーブルの整合性を保証できます。

于 2012-10-17T12:38:42.577 に答える