This project is read-only.
2

Closed

Unordered children with decimals may not work

description

Using the IgnoreCollectionOrder where the item in the collection is a decimal can cause false negatives. It looks like in c# decimals can be stored with trailing 0's. Thus 0 can be stored as 0.00 or 0.0. The unordered collection routines look like they are building a string representation of the object to compare to try and find a match. When calling to string on the above decimals, you get "0.0" and "0.00" which are not equal in a string-sense causing these two records not to match when they should. I added some simple logic to the GetMatchIndex class to strip trailing 0's from decimals when building the index.

Not sure if I can make a pull request for this but here is my code (probably could be refactored!)
if (propertyValue is decimal)
                    {
                        var value = propertyValue.ToString();
                        while (value[value.Length - 1] == '0')
                        {
                            value = value.Substring(0, value.Length - 1);
                        }
                        if (value[value.Length - 1] == '.')
                        {
                            value = value.Substring(0, value.Length - 1);
                        }
                        sb.AppendFormat("{0}:{1},", item, value);
                    }

file attachments

comments

gfinzer wrote Oct 26, 2015 at 6:07 PM

It will take a while until I get to this.

wrote Jan 26, 2016 at 9:25 AM

Paologx wrote Jan 26, 2016 at 9:26 AM

The described issue also happens loading an object by EF and comparing it with the original.
I modified the 'GetMatchIndex' method in 'IgnoreOrderLogic.cs' and it seems to work:
    private string GetMatchIndex(ComparisonResult result, List<string> spec, object currentObject)
    {
           ....
           ....

            if (propertyValue == null)
            {
                sb.AppendFormat("{0}:(null),",item);
            }
            else // ----------------->>>>>>>> modified code starts here
            {
                 string formatString = string.Format("{{0}}:{{1}}{0},", info.PropertyType.Name == "Decimal" ? ":N" : string.Empty);
                sb.Append(string.Format(formatString, item, propertyValue));
            } //---------------------------- end

Paologx wrote Jan 26, 2016 at 10:23 AM

There is an error in my previous post. The corrected line:

string formatString = string.Format("{{0}}:{{1{0}}},", info.PropertyType.Name == "Decimal" ? ":N" : string.Empty);

wrote Feb 29, 2016 at 10:42 AM

Halaveika wrote Feb 29, 2016 at 10:42 AM

Looks like this issue reproduces only for properties, and with IgnoreCollectionOrder = true.
See screens below

Halaveika wrote Feb 29, 2016 at 10:47 AM

Image

wrote Mar 5, 2016 at 2:22 AM