Как получить идентификатор от объекта для Auditlog в Entity Framework 6

audit-logging c# entity-framework entity-framework-6 savechanges

Вопрос

Я знаю, что это несколько похожих сообщений, но я не могу найти решение этой проблемы.

Я хочу добавить (вид) AudioLog при добавлении, изменении или удалении сущностей (soft-delete) в Entity Framework 6. Я переопределил SaveChanges и потому, что я хочу добавлять записи журнала для EntityStates, добавленных, измененных или удаленных, Я получаю список, прежде чем я вызову SaveChanges в первый раз. Проблема в том, что, поскольку мне нужно регистрировать, какая операция была выполнена, мне нужно проверить EntityState объектов. Но после вызова SaveChanges EntityState не изменяется для всех записей.

public override int SaveChanges()
{
    using (var scope = new TransactionScope())
    {
        var modifiedEntries = ChangeTracker.Entries()
            .Where(e => e.State == EntityState.Added || e.State == EntityState.Deleted || e.State == EntityState.Modified)
            .ToList();

        int changes = base.SaveChanges();
        foreach (var entry in modifiedEntries)
        {
            ApplyAuditLog(entry);
        }

        base.SaveChanges();
        scope.Complete();
        return changes;
    }
}

private void ApplyAuditLog(DbEntityEntry entry)
{
    ILog entity = entry.Entity as ILog;

    if (entity != null)
    {
        LogOperation operation;
        switch (entry.State)
        {
            case EntityState.Added:
                operation = LogOperation.CreateEntity;
                break;
            case EntityState.Deleted:
                operation = LogOperation.DeleteEntity;
                break;
            case EntityState.Modified:
                operation = LogOperation.UpdateEntity;
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }

        AuditLog log = new AuditLog
        {
            Created = DateTime.Now,
            Entity = entry.Entity.GetType().Name,
            EntityId = entity.Id,
            Operation = operation,
        };

        AuditLog.Add(log);
    }
}

Принятый ответ

Ахх ... Конечно! Идентификатор будет только «проблемой» для вновь добавленных объектов, поэтому, разделив список на два (один для измененных / удаленных и один для добавления), я создаю AuditLog в два этапа.

Для всех, кто хочет применить этот вид AuditLog, вот мой рабочий код:

public override int SaveChanges()
{
    using (var scope = new TransactionScope())
    {
        var addedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList();
        var modifiedEntries = ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted || e.State == EntityState.Modified).ToList();

        foreach (var entry in modifiedEntries)
        {
            ApplyAuditLog(entry);
        }

        int changes = base.SaveChanges();
        foreach (var entry in addedEntries)
        {
            ApplyAuditLog(entry, LogOperation.CreateEntity);
        }

        base.SaveChanges();
        scope.Complete();
        return changes;
    }
}

private void ApplyAuditLog(DbEntityEntry entry)
{
    LogOperation operation;
    switch (entry.State)
    {
        case EntityState.Added:
            operation = LogOperation.CreateEntity;
            break;
        case EntityState.Deleted:
            operation = LogOperation.DeleteEntity;
            break;
        case EntityState.Modified:
            operation = LogOperation.UpdateEntity;
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }

    ApplyAuditLog(entry, operation);
}

private void ApplyAuditLog(DbEntityEntry entry, LogOperation logOperation)
{
    ILog entity = entry.Entity as ILog;

    if (entity != null)
    {
        AuditLog log = new AuditLog
        {
            Created = DateTime.Now,
            Entity = entry.Entity.GetType().Name,
            EntityId = entity.Id,
            Operation = logOperation,
        };
        AuditLog.Add(log);
    }
}


Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему