c# - 如何从 Entity Framework 6 中的 Auditlog 实体获取 ID

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

我知道那里有几篇类似的帖子,但我找不到任何解决此问题的帖子。

我想在 Entity Framework 6 中添加、更改或删除实体(软删除)时添加(某种)AudioLog。我已经覆盖了 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);
    }
}

最佳答案

啊啊……当然了!! id 只会成为新添加的实体的“问题”,因此通过将列表分成两部分(一个用于修改/删除,一个用于添加),我分两个阶段创建 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);
    }
}

关于c# - 如何从 Entity Framework 6 中的 Auditlog 实体获取 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19797820/

相关文章:

ASP.NET Web API : JSON Serializing Circular References

c# - 在后面的代码中设置显示属性

c# - MySql Entity Framework 选择

c# - efcore 2.2 中的 Multi-Tenancy 配置

Entity Framework 迁移脚本中的 MySql 存储过程/循环

c# - DateTime 或 int 到 IQueryable 中的字符串?

c# - Delphi 函数转 C#

c# - 在 Web 应用程序中传递用户信息的最佳方式是什么?

c# - 将 byte[] 字符串转换回 byte[] 数组

c# - 无法跟踪实体类型 Model 的实例,因为已经在跟踪另一个具有相同键值 {'Id' } 的实例