entity-framework - 使用 Entity Framework Extended 的 Entity Framework 6 批量更新和 AuditLog

标签 entity-framework entity-framework-5 entity-framework-6 entity-framework-extended

我正在使用 Entity Framework 6 并使用 EntityFramework Extended 来执行一些批量更新和批量删除。批量更新和批量删除工作正常,但我还需要知道更新/删除的实体(即当前值和以前的值)。我认为使用 EntityFramework.Extended 提供的 AuditLogger 会为我提供更新或删除的实体的详细信息,但事实并非如此。例如,使用下面的代码即

var auditor =dbContext.BeginAudit();
dbContext.Addresses.Update(ent => new Address { AddressId = 1190 });
dbContext.SaveChanges();
var changes = auditor.LastLog;

这是简单的批量更新,将所有 addressId 更新为 1190。 如果我检查 changes.Entities,它返回 0 的计数,即一个空列表。

我所期望的是 changes.Entities 将包含所有具有旧值的“旧”实体,然后 addressId 更改为 1190

是我弄错了还是这确实是正确的行为?使用 Entity Framework 扩展批量更新/删除时如何获取所有更新实体的审计日志

谢谢

最佳答案

您应该启用审核员

var auditConfiguration = AuditConfiguration.Default;
auditConfiguration.IncludeRelationships = true;
auditConfiguration.LoadRelationships = true;
auditConfiguration.DefaultAuditable = true;

只需将它添加到您的应用程序初始化的地方,例如 Global.asax.cs

已编辑

据我所知,您无法使用 EF.Extended 获取旧值。 这是我的解决方案:

重写 Context 中的 SaveChanges 方法

public override int SaveChanges()
    {
        return SaveChanges(false);
    }

    public int SaveChanges(bool disableAudit)
    {
        var result = -1;
        try
        {
            if (!disableAudit)
            {
                foreach (var entity in ChangeTracker.Entries().Where(x => x.State == EntityState.Added ||
                                                                          x.State == EntityState.Modified ||
                                                                          x.State == EntityState.Deleted))
                {
                    ProccessAuditLog(entity);
                }
            }
        }
        catch (Exception ex)
        {
            // handle the ex here
        }
        finally
        {
            //save changes
            result = base.SaveChanges();
        }

        return result;
    }

并添加方法来处理审计日志:

private void ProccessAuditLog(DbEntityEntry entry)
    {
        var entity = entry.Entity;
        var entityType = GetEntityType(entity.GetType());

        var oldValue = Activator.CreateInstance(entityType); ;
        if (entry.State == EntityState.Modified)
        {
            // entry.OriginalValues doesn't load navigation properties for changed entity so we should reload the object from db to get it
            // save current values
            var newValue = Activator.CreateInstance(entityType);
            Mapper.DynamicMap(entity, newValue, entity.GetType(), entityType);

            // reload old values for entity from the db
            entry.Reload();
            Mapper.DynamicMap(entry.Entity, oldValue, entity.GetType(), entityType);

            // revert reloading changes in entity
            entry.CurrentValues.SetValues(newValue);
            entry.OriginalValues.SetValues(oldValue);
            entry.State = EntityState.Modified;
            entity = newValue;
        }

        if (entry.State == EntityState.Deleted)
        {
            // reload old values for entity from the db
            entry.Reload();
            Mapper.DynamicMap(entry.Entity, oldValue, entity.GetType(), entityType);

            // revert reloading changes in entity
            entry.OriginalValues.SetValues(oldValue);
            entry.State = EntityState.Deleted;
            entity = null;
        }

        // here is you can proccess old entity in 'oldValue' and new entity in 'entity'
        // then save your log to db using SaveChanges(true) to prevent StackOverFlow exception
    }

作为 Mapper,您可以使用 AutoMapper

获取基本实体类型而不是代理类型的方法:

private Type GetEntityType(Type entityType)
        {
            return entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies"
                    ? entityType.BaseType
                    : entityType;
        }

希望对你有帮助

关于entity-framework - 使用 Entity Framework Extended 的 Entity Framework 6 批量更新和 AuditLog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25065245/

相关文章:

c# - Entity Framework 查询中的多个连接

c# - AutoMapper.dll中出现 'AutoMapper.AutoMapperMappingException'类型的异常,但用户代码中没有处理

asp.net-mvc-4 - 将 WebSercurity.CreateAccount 与 TrasactionScope 中的其他查询一起使用,不启用 DTC

c# - Web api中的重复键问题

c# - 从虚拟集合中删除/添加内存使用

c# - Entity Framework 代码优先 - 初始代码迁移不起作用

entity-framework-6 - 属性表达式无效。表达式应该代表一个属性

c# - Linq to Entities - where 语句抛出 System.NotSupported 异常

entity-framework - 关于使用 Code First、Repository Pattern 和 n-Tier 的一些问题?

c# - Web Api JSON 中丢失的 EF TPH 继承