2016-01-03 7 views
6

Я переношу старый проект на ASP.NET 5 и Entity Framework 7. Я использовал первый подход базы данных (строительные леса DNX) для создания модели.Журнал аудита Entity Framework 7

старый проект основан на Entity Framework 4 и отслеживание аудита осуществляется путем переопределения SaveChanges метод DbContext:

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); 
} 

Мой вопрос, как я могу осуществить это в Entity Framework 7? Нужно ли мне сначала подходить коду?

+0

EF7 далеко не закончен, а не готов к производству. Сначала я бы пошел на EF6 и DbContext API. В накопителе EF7 все еще много элементов, которые должны быть реализованы до того, как он достаточно зрелый. –

+0

Мое понимание заключается в том, что вы можете реализовать его точно так же ... или хорошо в основном то же самое. – Seabizkit

+0

Лично вы должны передать идентификатор пользователя в метод, а не ссылаться на System.Web на связанном с данными слое. – Seabizkit

ответ

5

В основном у вас есть два пути достижения этой цели:

Использование ChangeTracker API (EF 6+):

Это способ, которым мы в настоящее время сделать это в EF 6 и он по-прежнему действует и работает 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 являются свойства, которые не существуют в вашем классе сущности. Значение и состояние этих свойств поддерживается исключительно в Track Track.

Другими словами, столбцы аудита не будут отображаться на ваших сущностях, которые, по-видимому, являются лучшим вариантом, сравнимым с приведенным выше, где вы должны включать их в свои объекты.

Чтобы реализовать свойства тени, сначала вы должны настроить их на своих объектах. Скажем, например, у вас есть объект пользователя, который должен иметь некоторые аудиторские столбцы:

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(); 
} 


Заключительные мысли:

Для реализации что-то вроде столбцов аудита, я возьму Shadow Properties, поскольку они связаны с перекрестными проблемами и не обязательно принадлежат моим доменным объектам, поэтому, если они будут реализованы таким образом, мои объекты домена будут хорошими и чистыми.

+0

Не могли бы вы мне помочь в проверке удаленных и m-m-отношений, используя API EF6, пожалуйста? –

0

Я работал над библиотекой, которая могла бы помочь.

Посмотрите на библиотеку Audit.EntityFramework, она перехватывает SaveChanges() и совместима с версиями EF Core.

Смежные вопросы