如何使用条目捕获“历史记录”.OriginalValues on EntityState.已删除

本文关键字:OriginalValues 历史记录 on EntityState 删除 记录 历史 何使用 | 更新日期: 2023-09-27 18:33:20

我目前正在开发一个基于 EF 的数据历史记录存储库,因为我不想使用作用于 INSERT、DELETE 等的触发器并使用 EF6 在代码中捕获所有 CRUD 操作。但是,当记录被删除时,我正在使用该条目。OriginalValues 集合及其属性名称,应用将引发异常。{"当前值不能用于处于"已删除"状态的实体。

使用条目。状态 MODIFIED状态 ADD 上的原始值工作正常。删除时如何使用原始值?

注意:希望上面/下面对手头的问题有意义,谢谢。

这是我案例陈述的片段:

switch( entry.State )
{
    case EntityState.Deleted:
    entry.OriginalValues
    .PropertyNames
    .Where( p => !ignore.Contains( p ) ) 
     //"ignore" is a list of fields not to worry about.
    .ToList()
        .ForEach( p =>
        HistoryList.Add( new History
        {
            Field1 = Value1,
            Field2 = Value2,
           ...  
         }
       )
     };
     break;                                                             

如何使用条目捕获“历史记录”.OriginalValues on EntityState.已删除

我认为您的示例缺少一段代码...在删除逻辑中使用"当前值"的部分,该逻辑会引发异常。

免责声明:我是GitHub上EF+(EntityFramework Plus(项目的所有者

相反,要创建自己的解决方案,您可以使用EF + Audit,它可以轻松跟踪更改,排除/包含实体或属性,并在数据库中自动保存审核条目。

如果您不想使用该库,所有源代码都可用于回答几乎所有有关审核的问题。

// using Z.EntityFramework.Plus; // Don't forget to include this.
var ctx = new EntityContext();
// ... ctx changes ...
var audit = new Audit();
audit.CreatedBy = "ZZZ Projects"; // Optional
ctx.SaveChanges(audit);
// Access to all auditing information
var entries = audit.Entries;
foreach(var entry in entries)
{
    foreach(var property in entry.Properties)
    {
    }
}

项目: http://entityframework-plus.net/

文档:实体框架审核跟踪上下文和跟踪更改

编辑:回答评论问题

是的,可以使用您的代码。

这正是 SaveChangesAsync 重载的作用:

public static async Task<int> SaveChangesAsync(this DbContext context, Audit audit, CancellationToken cancellationToken)
{
    audit.PreSaveChanges(context);
    var rowAffecteds = await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
    audit.PostSaveChanges();
    if (audit.CurrentOrDefaultConfiguration.AutoSavePreAction != null)
    {
        audit.CurrentOrDefaultConfiguration.AutoSavePreAction(context, audit);
        await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
    }
    return rowAffecteds;
}

编辑:回答子问题

嗨乔纳森, 什么是保存前更改和保存后更改

预保存更改

源代码

此方法将在保存发生之前获得所有可能的值。例如,删除的值。

此方法是 m

保存后更改

源代码

此方法基本上获得了一些在保存更改之前无法获取的值。例如,插入到数据库中的标识值。