0

In my code I am tracking change in my object by comparing current and old values using reflection over properties. I have one field of type decimal(5,2) in the database.

So when I pass, say 12 to the database from front end it gets stored as 12.00, this is fine. But if I try to save the object again with the value 12 the update tracker finds it different than the current value, so update tracker says

12 != 12.00

And so it records it as an update which actually is not because they are same values.

How can I check for the equivalence of such values?

EDIT

From update tracker I mean that I have written my own method SaveChanges in TemplateContext of EntityFramework which when called actually call the native SaveChanges method but before that it iterates through all the properties of the object using Reflection and tracks the change in the property and if there is a change then inserts in into one of my database tables to show the logs to the user of what all is changes and when.

So in that code I am checking the old value that is stored in the database and the new value that is provided by the UI.

So that property in my C# class is of type decimal and so I am not actually comparing int with decimal, I am checking decimal value with a decimal value.

So 12 is also stored in a decimal property and 12.00 is also stored in a decimal property

Edit 2

This is method that is tracking the change

public int SaveChanges(string personnelNo, string fullName, DateTime? now = null)
{
    var modifiedEntities = ChangeTracker.Entries().Where(p => p.State == EntityState.Modified).ToList();
    now = now ?? DateTime.UtcNow;

    foreach (var change in modifiedEntities)
    {
        var entityName = change.Entity.GetType().Name;
        var primaryKey = GetPrimaryKeyValue(change);

        foreach (var prop in change.OriginalValues.PropertyNames.Where(p=> skipUpdatesProperties.Any(s=> s==p) == false))
        {

          // below are the two lines which get original and current value
          // originalValue is coming from the database as 12.00
          // currentValue is coming from UI as 12
          // This is where it fails and says that the values are different 
          // I also tried removing ToString() also and comparing directly that also doesn't work
            var originalValue = change.OriginalValues[prop]?.ToString(); 
            var currentValue = change.CurrentValues[prop]?.ToString();
            if (originalValue != currentValue) //Only create a log if the value changes
            {
                //Create the Change Log
                var ut = new Model.UpdateTracker
                {
                    Id = Guid.NewGuid(),
                    TableName = entityName,
                    TableKey = primaryKey.ToString(),
                    FieldName = prop,
                    OldValue = originalValue,
                    NewValue = currentValue,
                    CreatedOn = now.Value,
                    CreatedBy = personnelNo,
                    CreatedByFullName = fullName
                };
                this.UpdateTrackers.Add(ut);
                this.Entry(ut).State = EntityState.Added;
            }
        }
    }

    return base.SaveChanges();
}
Pawan Nogariya
  • 8,330
  • 12
  • 52
  • 105
  • 1
    Your question isn't clear enough to provide any suggestion. How you are tracking those changes? post code for your so called *update tracker* – Rahul Jun 04 '19 at 10:13
  • How are you performing the comparison? In SQL `12` as an `int` and `12.00` as a `decimal(5,2)` have the same value. `SELECT CASE CONVERT(int,12) WHEN CONVERT(decimal(5,2),12.00) THEN 1 ELSE 0 END;` returns `1`, not `0`. – Thom A Jun 04 '19 at 10:13
  • 1
    You compare strings, not decimals. `"12"` and `"12.00"` are different strings. – György Kőszeg Jun 04 '19 at 10:35
  • @GyörgyKőszeg - I mentioned there that I tried removing `ToString` method also and tried to check the values directly, that also doesn't work – Pawan Nogariya Jun 04 '19 at 10:36
  • 1
    @PawanNogariya: If `OriginalValues[prop]` and `CurrentValues[prop]` have `object` return value, then please also note that equality check by `==` and `!=` will use a reference comparison even if the boxed values are decimal. Have you tried to use `Equals`? – György Kőszeg Jun 04 '19 at 10:40
  • @GyörgyKőszeg - Thanks Man!!!! You saved me! `object.Equals` method worked!! – Pawan Nogariya Jun 04 '19 at 10:47

1 Answers1

3

After detecting the real issue, adding as an answer, too:

If OriginalValues[prop] and CurrentValues[prop] have object return value, then please note that equality check by == and != will use a reference comparison even if the boxed values are decimals. Use Equals instead.

György Kőszeg
  • 17,093
  • 6
  • 37
  • 65