Cómo obtener la identificación de la entidad para Auditlog en Entity Framework 6

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

Pregunta

Sé que hay varias publicaciones similares, pero no puedo encontrar ninguna con una solución a este problema.

Quiero agregar un (tipo de) AudioLog al agregar, cambiar o eliminar entidades (eliminación suave) en Entity Framework 6. He anulado SaveChanges y porque solo quiero agregar entradas de registro para EntityStates Added, Modified o Deleted, Traigo la lista antes de llamar a SaveChanges la primera vez. El problema es que, como necesito registrar qué operación se ha ejecutado, debo inspeccionar el EntityState de las entidades. Pero después de llamar a SaveChanges, EntityState permanece sin cambios para todas las entradas.

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

Respuesta aceptada

Ahhh ... ¡¡Por supuesto !! La identificación solo será un "problema" para las entidades que se agregaron recientemente, por lo que al dividir la lista en dos (una para modificar / eliminar y otra para agregar), creo el AuditLog en dos etapas.

Para cualquier persona que quiera aplicar este tipo de AuditLog, aquí está mi código de trabajo:

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



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué