EF Core -更改跟踪子记录



我在我的记录上创建了一个更改日志,而ChangeTracking只从主类读取记录。

我已经添加了慢速加载,并且子类正在我的EntityEntry中加载,但是我不能通过入口捕获它们。

属性我班上

private void OnBeforeSaveChanges()
{
ChangeTracker.DetectChanges();
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{

if (entry.Entity is AuditLog || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry)
{
TableName = entry.Entity.GetType().Name,
UserId = _aplicationUser.GetId
};
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.AuditType = AuditType.Create;
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.AuditType = AuditType.Delete;
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.IsModified)
{
auditEntry.ChangedColumns.Add(propertyName);
auditEntry.AuditType = AuditType.Update;
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
break;
}
}
}
foreach (var auditEntry in auditEntries)
{
var auditDto = auditEntry.ToAudit();
AuditLogs.Add(new AuditLog(auditDto.Id, auditDto.UserId, auditDto.Type, auditDto.TableName, auditDto.DateTime,
auditDto.OldValues, auditDto.NewValues, auditDto.AffectedColumns, auditDto.PrimaryKey));
}
}

变更跟踪器以每个实体为基础进行报告。如果您有一个Parent实体和它下面的Child集合,并且对父实体和一个或多个子实体进行了更改,则由于对父实体的属性进行了更改,父实体仅显示在更改跟踪器中。它没有列出所有相关/子实体的属性。任何修改过的子实体都将作为子实体出现在ChangeTracker中。

例如:

var parent = context.Parents.Include(x => x.Children).Single(x => x.Id == parentId);
var oldestChild = parent.Children.OrderByDescending(x => x.Age).FirstOrDefault();
parent.SomeValue = newValue;
if (oldestChild != null)
oldestChild.OtherValue = someOtherValue;
context.SaveChanges();

在这种情况下,更改跟踪器将包含父如果,并且仅当newValue不同于现有的SomeValue。如果确实存在这样的子节点,那么变更跟踪器还将包含标记为oldestChild的子节点,并且someOtherValue与该子节点的OtherValue不同。如果Child的值是唯一实际发生更改的值,那么Change跟踪器将不包含该Child的Parent,而只包含Child引用。这意味着你不能真正捕获一个简单的"完整"。整个对象图的前后快照。(父节点及其前后的所有子节点,或者当它的一个子节点发生变化时,包括父节点)你可以这样做,但这将涉及到根据变化跟踪器中的内容将增量拼凑在一起。

当涉及到编写审计记录时,我建议仅为此目的使用有界DbContext,它只管理审计日志实体并保持实体结构尽可能简单。这样,主应用程序上下文可以拦截和检查更改,而不必担心审计更改,审计DbContext避免了这种开销,只执行原始写操作。

最新更新