Comment obtenir l'identifiant d'une entité pour Auditlog dans Entity Framework 6

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

Question

Je sais qu'il existe plusieurs articles similaires, mais je ne trouve aucune solution à ce problème.

Je souhaite ajouter un (en quelque sorte) AudioLog lors de l'ajout, de la modification ou de la suppression d'entités (soft-delete) dans Entity Framework 6. J'ai remplacé la SaveChanges et, par conséquent, je souhaite uniquement ajouter des entrées de journal pour EntityStates ajouté, modifié ou supprimé Je récupère la liste avant d'appeler SaveChanges pour la première fois. Le problème est que, parce que je dois consigner quelle opération a été exécutée, je dois inspecter le EntityState des entités. Mais après l’appel de SaveChanges, EntityState reste inchangé pour toutes les entrées.

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

Réponse acceptée

Ahhh ... Bien sûr !! L'identifiant ne sera un "problème" que pour les entités nouvellement ajoutées. Par conséquent, en scindant la liste en deux (une pour les modifications / suppressions et une pour les ajoutées), je crée AuditLog en deux étapes.

Pour tous ceux qui souhaitent appliquer ce type de AuditLog, voici mon code de travail:

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


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow