2016-07-04 2 views
1

Я работаю над веб-приложением, которое выполняет операции CRUD в некоторой таблице в базе данных SQL Server. В приложении, выполняющем эти операции, будет зарегистрирован пользователь.Удалить триггер для таблицы аудита

(Кстати, я использую Entity Framework)

Скажем, таблица

MyTable

  • MyTableId
  • SomeColumn
  • LastModifiedUserId
  • LastModifiedDate

а я есть таблица аудита, как

MyTableHistory

  • MyTableHistoryId
  • MyTableId
  • SomeColumn
  • ActionType --ins/обн/дель
  • ActionUserId
  • ActioDate

И я использую триггеры для вставки данных на таблицу аудита.

Вставки и обновления просты, консультируясь с таблицами «Вставленные и обновленные», чтобы найти пользователя, который изменил запись.

Но как насчет удалений? Любая идея, как я могу получить эту информацию?

+0

есть 'псевдо таблицы INSERTED', как вы сказали, но не' UPDATED' один. Также есть псевдо-таблица 'DELETED' – Lamak

+0

Но у DELETED просто будет LastModifiedUserId, который последний раз обновил запись, а не тот, кто удалил запись. Это то, что я хочу – DJPB

+0

'suser_sname()' это имя учетной записи, которая запускает запрос. –

ответ

0

Нет такой вещи, как updated стол. Две псевдо таблицы, доступные в триггерах DML, - inserted и deleted. В случае insert таблица deleted пуста, в случае delete таблица inserted пуста, в случае update обе таблицы заселены.
Вы можете создать три отдельных триггера для каждого действия (чтобы отличить ActionType) или попытаться объединить все в один триггер.
Примечание: учитывать несколько действий ряда.

0

Предполагая, что вы используете EF для добавления информации о том, какой пользователь обновляет записи, самый простой способ захватить эту информацию состоит в том, чтобы EF выполнял двухэтапный процесс (UPDATE, DELETE) по данным, которые вы хотите удалить. Затем вам нужно будет интерпретировать две строки аудита как часть одной и той же операции.

Существует гораздо более активное решение, которое «может» работать, но я его не тестировал. Ниже приведена дополнительная информация, если вы хотите изучить ее.

Другой вариант вообще стоит отказаться от запуска аудита (что является проблематичным по этой причине) и использовать Entity Framework вместо этого. Ниже приведен пример того, как можно было бы сделать это путем переопределения метода SaveChanges:

public virtual IEnumerable<System.Data.Entity.Infrastructure.DbEntityEntry> ChangedEntries() 
{ 
    return ChangeTracker.Entries().Where(x => 
     x.State == EntityState.Added || 
     x.State == EntityState.Deleted || 
     x.State == EntityState.Modified); 
} 

public virtual int SaveChanges(string userName) 
{ 
    var changes = ChangedEntries(); 

    foreach (var entry in changes) 
    { 
     var eventType = entry.State == EntityState.Added ? "A" : entry.State == EntityState.Deleted ? "D" : "U"; 
     var entityType = ObjectContext.GetObjectType(entry.Entity.GetType()).Name; 

     var oldValues = entry.State == EntityState.Added ? null : JsonConvert.SerializeObject(entry.OriginalValues.ToObject()); 
     var newValues = entry.State == EntityState.Deleted ? null : JsonConvert.SerializeObject(entry.CurrentValues.ToObject()); 

     oldValues = oldValues?.Substring(0, Math.Min(oldValues.Length, 4000)); 
     newValues = newValues?.Substring(0, Math.Min(newValues.Length, 4000)); 

     AuditItems.Add(
      new AuditItem 
      { 
       EventTime = DateTime.Now, 
       UserName = userName, 
       EntityType = entityType, 
       EventType = eventType, 
       OldValues = oldValues, 
       NewValues = newValues 
      } 
     ); 
    } 

    return base.SaveChanges(); 
} 

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

  • Нет связанных вопросов^_^