ChangeTracker.Entries() CurrentValue equals OriginalValue in EF7

c# entity-framework entity-framework-core

Question

I have a issue in EF7/asp.Net Core application. In my context I create a method 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();
    }

and method 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;
    }

Unfortunatlly the change.Property(prop.Name).CurrentValue always equals OriginalValue, so the if originalValue.ToString() != currentValue.ToString()

always return false.

1
2
8/18/2018 4:29:34 PM

Accepted Answer

This will not exactly answer your question since I cannot reproduce this issue but this may help you.

In EF Core, the PropertyEntry class has now an IsModified property which let you know if the value has been modified or not.

You should use it instead:

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);
}

Disclaimer: I'm the owner of the project Entity Framework Plus

The Library has an Audit Feature (Supporting EF Core) which you may use or get inspired by to create your auditing (The code is Open Source).

Documentation: EF+ Audit

3
8/22/2018 10:21:39 PM

Popular Answer

Replace:

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

to:

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow