.net 记录实体操作日志--通过DbContext单次批量记录本次数据库操作中所有实体的更新情况
一、先看需求
需求就是在我们的业务中存在查看修改日志的情况,比如:甲修改了乙的身份证号,丙想知道是谁修改了乙的信息,修改了哪些信息。
二、常规方案
在修改乙的信息的方法中记录一下(代码就不写了,常规记录日志的方法应该很简单),如果本次修改操作中仅更新了乙的信息这一个实体,那么只记录一次即可,但是如果在本次修改操作中还修改了n个其他的实体,那么我们就要再记录n次,还可能会有遗漏的情况。
三、通过DbContext的changgetracker来一次性记录本次操作中所有实体的修改情况
直接贴代码了,具体的说明在注释中
private void GenerateLogs(DbStoreBase dbStore)
{
// 通过changgetracker即可找到本次操作中跟踪到的实体
var list = dbStore.ChangeTracker.Entries();
// 找出本次操作中所有修改过的实体
var entryModifieds = list.Where(e => e.State == EntityState.Modified).ToList();
var userId = loginUserEquipment.UserId;
foreach (var entry in entryModifieds)
{
var entity = entry.Entity;
// 找到本实体中的主键
var primaryKeyName = entry.CurrentValues.Properties.Where(e => e.IsPrimaryKey()).FirstOrDefault()?.Name;
if (primaryKeyName.IsNullOrEmpty())
{
continue;
}
var noteId = entry.Property(primaryKeyName)?.CurrentValue;
var updateContexts = new List<EntityUpdateContext>();
var properties = entry.CurrentValues.Properties.Where(i => entry.Property(i.Name).IsModified);
foreach (var item in properties)
{
var property = entry.Property(item.Name);
if (property == null)
{
continue;
}
// 找到更改过的字段
if (property.CurrentValue.ToStringEmpty() != property.OriginalValue.ToStringEmpty())
{
var customProperty = new CustomPropertyInfo(item.PropertyInfo);
// EntityUpdateContext就是记录修改记录的一个类,只有下面这三个字段,为了便于记录
updateContexts.Add(new EntityUpdateContext
{
CustomPropertyInfo = customProperty,
OriginalValue = property.OriginalValue,
TargetValue = property.CurrentValue
});
}
}
if (updateContexts.Count == 0)
{
continue;
}
// 这是具体的记录方法 可以使用自己的
histroyDataService.Update(userId, entity, noteId, updateContexts, true);
}
}
浙公网安备 33010602011771号