c# - Entity Framework DbContext SaveChanges() OriginalValue 不正确

标签 c# entity-framework entity-framework-4.1 ef-code-first

我正在尝试使用 EF 4.1 实现 AuditLog,方法是重写在以下位置讨论的 SaveChanges() 方法:

不过,我对“已修改”条目有疑问。每当我尝试获取相关属性的 OriginalValue 时,它的值始终与 CurrentValue 字段中的值相同。

我首先使用这段代码,它成功地识别出被修改的条目:

public int SaveChanges(string userID)
{

    // Have tried both with and without the following line, and received same results:
    // ChangeTracker.DetectChanges();

    foreach (
      var ent in this.ChangeTracker
                     .Entries()
                     .Where( p => p.State == System.Data.EntityState.Added ||
                                     p.State == System.Data.EntityState.Deleted ||
                                     p.State == System.Data.EntityState.Modified ))
    {
        // For each change record, get the audit record entries and add them
        foreach (AuditLog log in GetAuditRecordsForChange(ent, userID))
        {
            this.AuditLog.Add(log);
        }

    }

    return base.SaveChanges();
}

问题出在这个(缩写代码):

    private List<AuditLog> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userID)
    {
        if (dbEntry.State == System.Data.EntityState.Modified)
        {
            foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
            {
                if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName),
                    dbEntry.CurrentValues.GetValue<object>(propertyName)))
                {
                        // It never makes it into this if block, even when
                        //    the property has been updated.
                }

                // If I updated the property "Name" which was originally "OldName" to the value "NewName" and then break here and inspect the values by calling:
                //      ?dbEntry.OriginalValues.GetValue<object>("Name").ToString()

                // the result will be "NewName" and not "OldName" as expected
             }
         }
    }

奇怪的是,调用 dbEntry.Property(propertyName).IsModified(); 将 在这种情况下返回 true。只是 OriginalValue 里面没有期望值。有人愿意帮我指出正确的方向吗?我似乎无法让它正常工作。

最佳答案

当 EF 从数据库中检索实体时,它会拍摄该实体所有属性的原始值的快照。稍后,随着对这些属性的值进行更改,原始值将保持不变,而当前值将发生变化。

但是,要实现这一点,EF 需要在整个过程中跟踪实体。在 Web 或其他 n 层应用程序中,通常将值发送到客户端,并处理用于查询实体的上下文。这意味着实体现在不再被 EF 跟踪。这是很好的做法。

一旦应用程序回发,实体就会使用来自客户端的值进行重构,然后重新附加到上下文并设置为已修改 状态。但是,默认情况下,从客户端返回的唯一值是当前值。原始值丢失。通常这无关紧要,除非您正在进行乐观并发或希望非常小心地只更新真正改变的值。在这些情况下,原始值也应该发送到客户端(通常作为网络应用程序中的隐藏字段),然后作为附加过程的一部分重新应用为原始值。这在上面的示例中没有发生,这就是原始值未按预期显示的原因。

关于c# - Entity Framework DbContext SaveChanges() OriginalValue 不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9588352/

相关文章:

c# - 追加到 txt 文件会产生奇怪的字符

asp.net - Entity Framework 4 - 从模型更新数据库架构。不删除表数据

c# - 在 EF5 中是否可以生成具有表值的枚举?

c# - FirstOrDefault() 方法是处理这种情况的好方法吗

code-first - 更改 EF 4.1 Code First 默认数据库位置

c# - wcf rest ierrorhandler webfaultexception

c# - 想在 ASP.NET MVC 中每天执行一次查询

c# - 如何使用C#设置环境变量Path

c# - 在 IQueryable<T> 上应用多个组函数

asp.net-mvc - 如何使用 Entity Framework 代码优先方法执行SP?