简体   繁体   中英

Exception when using LINQ orderby: "Failed to compare two elements in the array"

Here is sample code to reproduce the exception:

using Microsoft.EntityFrameworkCore.Metadata.Conventions;
using Microsoft.EntityFrameworkCore;

namespace Demo
{
    [Keyless]
    public class Contact
    {
        public string Name { get; set; } = default!;
        public string? Address { get; set; } = default!;
        public int? CCode { get; set; } = 0;
        public int OtherValue { get; set; } = 0;
    }

    public class Foo
    {
        public static void Main()
        {
            List<Contact> raw = new();
            raw.Add(new Contact { CCode = 1, Name = "Foo", Address = "Bar" });
            raw.Add(new Contact { CCode = 2, Name = "Foo", Address = "Bar" });
            ProcessRawResults(raw);
        }
        public static void ProcessRawResults(List<Contact> raw)
        {
            var q = from i in raw
                    group i by new { i.CCode, i.Name, i.Address } into g
                    orderby g.Key
                    select g;

            foreach (var group in q)
            {
            }
        }
    }
}

When executing this program, an exception is thrown when execution reaches foreach (var group in q) :

System.InvalidOperationException: 'Failed to compare two elements in the array.'

Inner Exception

ArgumentException: At least one object must implement IComparable

I have looked at other SO questions about this error message occurring when trying to Sort a List; but in this code I'm not sure which operation needs the comparator. It seems like the orderby g.Key operation might need to compare the anonymous class in the group, but then shouldn't the anon class have a default comparator? Or if it doesn't, I'm not sure where to put the code to implement this.

Confusingly, if I take i.CCode out of the group i by new line, then the exception doesn't happen any more.


Background: My real project is a Blazor app using EFCore 6, and am receiving a List<Contact> from a Stored Procedure result, so it has to be [Keyless] . I have to work with the existing Stored Procedure unmodified, so am performing a transformation of the result in my code. I hope to collapse the set of results so that all entries with the same (CCode, Name, Address) result in a single row, and I'll concatenate the OtherValue into a list within that single row.

I guess it's because int? is actually Nullable<int> and Nullable<T> doesn't implement IComparable . I just tested your code but changed the grouping to this:

group i by new { CCode = i.CCode.HasValue ? i.CCode.Value : (int?)null, i.Name, i.Address } into g

and it seemed to work. It didn't throw that exception, at least.

Anonymous type do not have comparator, specify oder by properties:

var q = from i in raw
        group i by new { i.CCode, i.Name, i.Address } into g
        orderby g.Key.CCode, g.Key.Name, g.Key.Address 
        select g;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM