locked
Having an issue with linq order by with a custom comparer not finishing. RRS feed

  • Question

  • User-1355914297 posted

    The comparer gets called over and over and never finishes when I call orderProb().ToList().  Am I doing something wrong?

    public class PreferredAddressComparer : IComparer<AddressTest>
        {
            public int Compare(AddressTest x, AddressTest y)
            {
                //default address
                if (x.defaultAddress == true)
                {
                    return 1;
                }
    
                if (y.defaultAddress == true)
                {
                    return -1;
                }
    
                var addressTypeOrder = new[] { 1, 4, 2, 3, 5 };
                foreach (var addressTypeId in addressTypeOrder)
                {
                    if (x.addressTypeId == addressTypeId)
                    {
                        return 1;
                    }
    
                    if (y.addressTypeId == addressTypeId)
                    {
                        return -1;
                    }
                }
    
                return 0;
            }
        }
    
        public class AddressTest
        {
            public int addressId { get; set; }
            public bool? defaultAddress { get; set; }
            public int? addressTypeId { get; set; }
        }
    ---------------------------------------
    
    public IEnumerable<AddressTest> orderProb()
            {
                var addresses = new[] {new AddressTest
                {
                   addressId = 1,
                   addressTypeId = 1
                },
                new AddressTest
                {
                    addressId = 2,
                    addressTypeId = 2
                } };
                var comparer = new PreferredAddressComparer();
                return addresses.OrderBy(x => x, comparer);
            }
    

    Friday, December 30, 2016 5:03 PM

All replies

  • User-707554951 posted

    Hi abram27,

    For your problem, I suggest you could replace ToList() method with  AsEnumerable() method.

    Code as below:

     protected void Page_Load(object sender, EventArgs e)
            {
                 var result = orderProb().AsEnumerable();        
            }
            public class PreferredAddressComparer : IComparer<AddressTest>
            {
                public int Compare(AddressTest x, AddressTest y)
                {
                    //default address
                    if (x.defaultAddress == true)
                    {
                        return 1;
                    }
    
                    if (y.defaultAddress == true)
                    {
                        return -1;
                    }
    
                    var addressTypeOrder = new[] { 1, 4, 2, 3, 5 };
                    foreach (var addressTypeId in addressTypeOrder)
                    {
                        if (x.addressTypeId == addressTypeId)
                        {
                            return 1;
                        }
    
                        if (y.addressTypeId == addressTypeId)
                        {
                            return -1;
                        }
                    }
    
                    return 0;
                }
            }
            public class AddressTest
            {
                public int addressId { get; set; }
                public bool? defaultAddress { get; set; }
                public int? addressTypeId { get; set; }
            }
            public IEnumerable<AddressTest> orderProb()
            {
                var addresses = new[] {new AddressTest
                {
                   addressId = 1,
                   addressTypeId = 1
                },
                new AddressTest
                {
                    addressId = 2,
                    addressTypeId = 2
                } };
                var comparer = new PreferredAddressComparer();
                return addresses.OrderBy(x => x, comparer);
            }

    Code above works well without calling compare over and over and never finishes.

    Best Regard

    Cathy

    Tuesday, January 3, 2017 2:50 AM
  • User-1355914297 posted

    AsEnumerable doesn't force execution, can you actually read results?

    Tuesday, January 3, 2017 3:55 PM
  • User-1355914297 posted

    Ended up changing the order by to the following if anyone else has the same issue.  Still curious why my original post doesn't work.

    addresses.OrderBy(x => _getSortOrder(x)).FirstOrDefault();
    ----------------------------------------------------------
    private readonly int?[] _addressTypeOrder = { 1, 4, 2, 3, 5 };
    private int _getSortOrder(Address address)
            {
                if (address.defaultAddress == true)
                {
                    return 1;
                }
    
                for (int i = 0; i < _addressTypeOrder.Length - 1; i++)
                {
                    if (address.addressTypeId == _addressTypeOrder[i])
                    {
                        return i + 2;
                    }
                }
    
                return 7;
            }

    Wednesday, January 4, 2017 6:50 PM