2016-01-03 21 views
6

私は古いプロジェクトをASP.NET 5とEntity Framework 7に移植しています。データベースの最初のアプローチ(DNX足場)を使用してモデルを作成しました。Entity Framework 7監査ログ

古いプロジェクトは、Entity Frameworkの4に基づくものであり、監査の追跡がDbContextSaveChanges方法オーバーライドして実装されます。私の質問はどのように私はEntity Frameworkを7でこれを実装することができ、ある

public override int SaveChanges(System.Data.Objects.SaveOptions options) 
{ 
    int? UserId = null; 
    if (System.Web.HttpContext.Current != null) 
     UserId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)) 
    { 
     Type EntityType = entry.Entity.GetType(); 

     PropertyInfo pCreated = EntityType.GetProperty("Created"); 
     PropertyInfo pCreatedById = EntityType.GetProperty("CreatedById"); 
     PropertyInfo pModified = EntityType.GetProperty("Modified"); 
     PropertyInfo pModifiedById = EntityType.GetProperty("ModifiedById"); 

     if (entry.State == EntityState.Added) 
     { 
      if (pCreated != null) 
       pCreated.SetValue(entry.Entity, DateTime.Now, new object[0]); 
      if (pCreatedById != null && UserId != null) 
       pCreatedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
     if (pModified != null) 
      pModified.SetValue(entry.Entity, DateTime.Now, new object[0]); 
     if (pModifiedById != null && UserId != null) 
      pModifiedById.SetValue(entry.Entity, UserId, new object[0]); 
     } 
    } 

    return base.SaveChanges(options); 
} 

を?コードを最初にやってみる必要がありますか?これは、我々は現在、EF 6でそれを行う方法です

、それはまだです:

ChangeTrackerのAPIを使用して(EF 6+):

+0

EF7はまだ完成しておらず、まったく生産準備ができていません。私は最初にEF6とDbContext APIに行くだろう。成熟する前に実装されなければならないEF7バックログにはまだ多くのアイテムがあります。 –

+0

私の理解では、あなたはまったく同じ方法で実装することができます...または基本的に同じです。 – Seabizkit

+0

個人的には、データ関連レイヤーでSystem.Webを参照するのではなく、メソッドにユーザーIDを渡す必要があります。 – Seabizkit

答えて

5

は、基本的には次の2つのこれを達成する方法を持っています有効とEF 7のために働いて:あなたはあなたのエンティティが監査フィールドのための共通のインタフェースを実装していることを確認する必要があり

まず:

public interface IAuditableEntity 
{ 
    int? CreatedById { get; set; } 

    DateTime Created { get; set; } 

    int? ModifiedById { get; set; } 

    DateTime Modified { get; set; } 
} 


その後は、SaveChangesメソッドをオーバーライドして、監査の値と各共通フィールドを更新することができます。

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedEntries = ChangeTracker.Entries<IAuditableEntity>() 
      .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<IAuditableEntity> entry in modifiedEntries) 
    { 
     entry.Entity.ModifiedById = UserId; 
     entry.Entity.Modified = DateTime.Now; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Entity.CreatedById = UserId; 
      entry.Entity.Created = DateTime.Now; 
     } 
    } 

    return base.SaveChanges(); 
} 


EF 7新しい "シャドウプロパティ" 機能を使用して:

Shadow properties

をしていますエンティティクラスに存在しないプロパティ。これらのプロパティの値と状態は、変更トラッカーで純粋に保持されます。

つまり、エンティティに監査列が表示されることはありません。エンティティに監査列が含まれている必要があります。

シャドウプロパティを実装するには、まずそれらをエンティティに設定する必要があります。のは、たとえばあなたには、いくつかの監査列を持つ必要があるユーザーオブジェクトを持っているとしましょう:

protected override void OnModelCreating(ModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<User>().Property<int>("CreatedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Created"); 

    modelBuilder.Entity<User>().Property<int>("ModifiedById"); 

    modelBuilder.Entity<User>().Property<DateTime>("Modified"); 
} 


は一度設定、今はSaveChangesメソッドでそれらにアクセスすることができます()オーバーライドし、それに応じて値を更新:

public override int SaveChanges() 
{ 
    int? userId = null; 
    if (System.Web.HttpContext.Current != null) 
     userId = (from user in Users.Where(u => u.UserName == System.Web.HttpContext.Current.User.Identity.Name) select user.Id).SingleOrDefault(); 

    var modifiedBidEntries = ChangeTracker.Entries<User>() 
     .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); 

    foreach (EntityEntry<User> entry in modifiedBidEntries) 
    { 
     entry.Property("Modified").CurrentValue = DateTime.UtcNow; 
     entry.Property("ModifiedById").CurrentValue = userId; 

     if (entry.State == EntityState.Added) 
     { 
      entry.Property("Created").CurrentValue = DateTime.UtcNow; 
      entry.Property("CreatedById").CurrentValue = userId; 
     } 
    } 

    return base.SaveChanges(); 
} 


最終的な考え:監査列のようなものを実装するための

、私が取りますよこれらはクロスカッティングの問題であり、必ずしも自分のドメインオブジェクトに属しているわけではないので、この方法で実装すると、ドメインオブジェクトがきれいできれいに保たれます。

+0

EF6 APIを使用して、削除されたm-m関係を監査する手助けをしてください。 –

0

私は役に立つかもしれない図書館で働いています。

Audit.EntityFrameworkライブラリを見ると、SaveChanges()を傍受し、EFコアバージョンと互換性があります。

関連する問題