gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 08:34:58 34 4
gpt4 key购买 nike

我正在使用 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/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com