【问题标题】:ChangeTracker.Entries() CurrentValue equals OriginalValue in EF7ChangeTracker.Entries() CurrentValue 等于 EF7 中的 OriginalValue
【发布时间】:2018-10-10 15:26:57
【问题描述】:

我在 EF7/asp.Net Core 应用程序中遇到问题。在我的上下文中,我创建了一个方法 Save:

    public int Save()
    {
        ChangeTracker.DetectChanges();
        var modifiedEntities = ChangeTracker.Entries()
            .Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified || p.State == EntityState.Detached).ToList();
        var now = DateTime.UtcNow;

        foreach (var change in modifiedEntities)
        {
            var entityName = change.Entity.GetType().Name;
            var primaryKeyValue = GetPrimaryKeyValue(change.Entity);
            foreach (var prop in change.Entity.GetType().GetTypeInfo().DeclaredProperties)
            {
                if (!prop.GetGetMethod().IsVirtual)
                {
                    var currentValue = change.Property(prop.Name).CurrentValue;
                    var originalValue = change.Property(prop.Name).OriginalValue;
                    if (originalValue.ToString() != currentValue.ToString())
                    {
                        var changeLoged = new ChangeLog
                        {
                            PropertyName = prop.Name,
                            EntityName = entityName,
                            PrimaryKeyValue = primaryKeyValue,
                            DateChange = now,
                            OldValue = originalValue.ToString(),
                            NewValue = currentValue.ToString(),
                            ChangedBy = "test"
                        };
                        ChangeLog.Add(changeLoged);
                    }
                }
            }
        }
        return base.SaveChanges();
    }

和方法GetPrimaryKeyValue:

protected virtual int GetPrimaryKeyValue<T>(T entity)
    {
        var test = entity;
        var test2 = test.GetType();
        var keyName = this.Model.FindEntityType(test2).FindPrimaryKey().Properties
            .Select(x => x.Name).Single();
        var result = (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
        if (result < 0)
            return -1;

        return result;
    }

不幸的是 change.Property(prop.Name).CurrentValue 总是等于 OriginalValue,所以 if originalValue.ToString() != currentValue.ToString()

总是返回 false。

【问题讨论】:

  • 看看Audit.EntityFramework 库。它会拦截您的上下文的 SaveChanges 以生成详细的 EF CRUD 操作审核日志。
  • 这被标记为 entity-framework 和 entity-framework-core 有点令人困惑,因为它们是不同的框架。

标签: c# entity-framework entity-framework-core


【解决方案1】:

替换:

var originalValue = change.Property(prop.Name).OriginalValue;

到:

var originalValue = change.GetDatabaseValues().GetValue<object>(prop.Name);

【讨论】:

    【解决方案2】:

    这不会完全回答您的问题,因为我无法重现此问题,但这可能会对您有所帮助。

    在 EF Core 中,PropertyEntry 类现在有一个 IsModified 属性,可以让您知道值是否已被修改。

    你应该改用它:

    if (change.Property(prop.Name).IsModified)
    {
        var changeLoged = new ChangeLog
        {
            PropertyName = prop.Name,
            EntityName = entityName,
            PrimaryKeyValue = primaryKeyValue,
            DateChange = now,
            OldValue = originalValue.ToString(),
            NewValue = currentValue.ToString(),
            ChangedBy = "test"
        };
        ChangeLog.Add(changeLoged);
    }
    

    免责声明:我是项目的所有者Entity Framework Plus

    库有一个审计功能(支持 EF Core),您可以使用它或从中获得灵感来创建您的审计(代码是开源的)。

    文档:EF+ Audit

    【讨论】:

    • 如果它与原始不同,或者如果它已被写入,是否设置为修改?
    猜你喜欢
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2016-04-09
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多