Entity Framework 6: аудит / отслеживание изменений

у меня есть мой основной проект на C#.

Я работаю над базой данных, где в некоторых таблицах есть столбцы "user_mod" и "date_mod" для знака кто и когда сделал некоторые моды и то же самое с "data_new"и " user_new".

мой вопрос: есть ли способ, чтобы централизовать и сделать эти данные вставляются автоматически, когда я создаю экземпляр dbContext?

Если нет, я буду использовать инструмент аудита. Я видел некоторые из них, но есть проблема: все эти, требуется некоторый код в моей модели. Но я не хочу писать в своей модели, потому что, если мне придется ее изменить, я потеряю моды. Можно ли использовать аудиторский след для EF6 без записи в файл(ы) модели? Как?

EDIT:

моя попытка переопределить saveChanges.

public partial class PieEntities : DbContext
{
    public override int SaveChanges(System.Data.Objects.SaveOptions options)
    {
        var timestamp = DateTime.Now;

        EntityState es = EntityState.Added;
        ObjectStateManager o = new ObjectStateManager();

        foreach (ObjectStateEntry entry in o.GetObjectStateEntries(EntityState.Added ))  {
            if (entry.Entity.GetType() == typeof(TabImpianti)) {
                TabImpianti impianto = entry.Entity as TabImpianti;
                impianto.DATA_INS = timestamp;
                impianto.DATA_MOD = timestamp;
                string u = mdlImpostazioni.p.UserName;
                impianto.USER_INS = u;
                impianto.USER_MOD = u;
            }
        }
        return base.SaveChanges(options);
    }
}

UPDATE: я суммировал здесь.

3 ответов


при использовании EF6 в DbContext можно использовать ChangeTracker на SaveChanges переопределить, чтобы найти добавленные / измененные сущности пользовательского типа, например IAuditedEntity.

public interface IAuditedEntity {
  string CreatedBy { get; set; }
  DateTime CreatedAt { get; set; }
  string LastModifiedBy { get; set; }
  DateTime LastModifiedAt { get; set; }
}

public override int SaveChanges() {
  var addedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
    .Where(p => p.State == EntityState.Added)
    .Select(p => p.Entity);

  var modifiedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>()
    .Where(p => p.State == EntityState.Modified)
    .Select(p => p.Entity);

  var now = DateTime.UtcNow;

  foreach (var added in addedAuditedEntities) {
    added.CreatedAt = now;
    added.LastModifiedAt = now;
  }

  foreach (var modified in modifiedAuditedEntities) {
    modified.LastModifiedAt = now;
  }

  return base.SaveChanges();
}


есть один способ сделать это: вы можете создать частичный класс с тем же именем, что и контекст объекта, и реализовать переопределение SaveChanges метод. В этом переопределении вы можете просмотреть все изменения, которые будут перенесены в БД, и обработать их.

вы можете обрабатывать их любым способом, в следующем примере я создал интерфейс IAutoTimestampEntity, который содержит дату создания и дату изменения. Любой объект этого типа будет автоматически обновляться со временем перемен.

public override int SaveChanges(System.Data.Objects.SaveOptions options)
{
    var timestamp = DateTime.Now;

    foreach (var InsertedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>())
    {
        InsertedAutoTimestampEntity.CreationDate = timestamp;
        InsertedAutoTimestampEntity.ModificationDate = timestamp;
    }

    foreach (var UpdatedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>())
    {
        UpdatedAutoTimestampEntity.ModificationDate = timestamp;
    }

    return base.SaveChanges(options);
}

вы можете использовать тот же принцип, или вы можете посмотреть на тип каждого измененного объекта в деталях. Мне нравится декларативный аспект интерфейса. Это позволяет вам эксплицитно раскрывать один аспект автоматизации, а не позволять это делать тихо слоем EF.

если у вас DbContext вместо ObjectContext ног DbContext to IObjectContextAdapter к ObjectStateManager