Не удается выполнить аудит на платформе Entity Framework. Я не могу помочь? - PullRequest
2 голосов
/ 07 декабря 2010

это мой третий день, и это сводит меня с ума.

Необходимость аудита всякий раз, когда я делаю, вставка, явно привязанная к SaveChanges, мне не подходит, так как мне нужен новый GeneratedID, который вы получаете при добавленииновая запись

Я переопределил SaveChanges, и теперь я могу получить вновь добавленные записи с первичным ключом.

Моя проблема заключается в том, что у меня теперь есть newLog для вставки, и мне нужно вызватьСнова SaveChanges.

Либо я попадаю в бесконечный цикл, либо вставляю запись дважды.

Как вы проверяете вставку, если вам нужен первичный ключ вновь вставленного объекта, например (CustomerId)

  public override int SaveChanges(SaveOptions options)
  {
     int changes = base.SaveChanges(SaveOptions.DetectChangesBeforeSave);
     IEnumerable<ObjectStateEntry> entries = Context.ObjectStateManager.GetObjectStateEntries(EntityState.Added);
     foreach (ObjectStateEntry entry in entries)
     {
          var auditLog=CreateAuditLog(Entry);
     }

 //Because I have saved I now got the new Id. I now need to save the newly created log and therefore
 //I call save again but now this will save again all the previous stuff too or get in a infinite loop
 //Is there a way I could just save the newly added stuff what is the workaround?

    base.SaveChanges();


    return changes;
  }

Как можно провести аудит при вставке?любой пример?

Ответы [ 4 ]

4 голосов
/ 07 декабря 2010

У вас есть , чтобы сделать это в коде?

Почему бы не использовать триггер в базе данных и не скопировать запись в таблицу аудита?

Anальтернативой может быть создание Dictionary<T,bool> для хранения проверенных предметов.

После того, как вы проверили предмет, установите ключ (bool) в значение true, чтобы показать, что он был проверен.

Или другой вариант - вместо немедленного сохранения аудита сохранить его в каком-то другом хранилище (в памяти, кэше, сеансе и т. Д.).

Затем, в зависимости от того, какое приложение вы используете, вы можете зафиксироватьэти проверенные объекты попадают в базу данных в конце «запроса».

Я просто подбрасываю идеи здесь - но я все еще верю, что триггер будет самым простым / безопасным делом здесь.

0 голосов
/ 29 апреля 2013

Немного поздно в игре, но я наткнулся на этот пост, так как у меня была та же проблемаВызов метода ObjectStateEntry.AcceptChanges сработал для меня.Статья MSDN здесь

0 голосов
/ 07 декабря 2010

Я думаю, вы можете попробовать что-то немного другое:

Создайте другой класс, который управляет сохранением ваших изменений и сохранением журнала аудита, как показано ниже (представьте, что это своего рода псевдокод - он не завершен, но должен дать вам представление):

public void Save(Context context)
{
    using (Transaction scope = new TransactionScope)
    {

    context.SaveChanges(SaveOptions.DetectChangesBeforeSave);

    auditContext = new MyAuditContext();
    var auditLog=CreateAuditLog(Entry);

    myAudtContext.SaveChanges(SaveOptions.DetectChangesBeforeSave);

    scope.Complete();

    context.AcceptChanges();

    myAuditContext.AcceptChanges()
}

}

0 голосов
/ 07 декабря 2010

Я не знаю, как выглядит ваш журнал аудита, но если в нем есть ссылка на Entry, вы не можете CreateAuditLog (Entry) до вызова base.SaveChanges (), и все идентификаторы должны сработать. *

...