简体   繁体   English

使用 LINQ orderby 时出现异常:“无法比较数组中的两个元素”

[英]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) :执行此程序时,执行到foreach (var group in q)时抛出异常:

System.InvalidOperationException: 'Failed to compare two elements in the array.' System.InvalidOperationException:“无法比较数组中的两个元素。”

Inner Exception内部异常

ArgumentException: At least one object must implement IComparable ArgumentException:至少一个 object 必须实现 IComparable

I have looked at other SO questions about this error message occurring when trying to Sort a List;我已经查看了有关尝试对列表进行排序时出现的此错误消息的其他 SO 问题; 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?似乎orderby g.Key操作可能需要比较组中的匿名 class,但是匿名 class 不应该有默认比较器吗? 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.令人困惑的是,如果我用新行将i.CCodegroup i by new中取出,那么异常就不会再发生了。


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] .背景:我的真实项目是一个使用 EFCore 6 的 Blazor 应用程序,并且正在从存储过程结果中接收到一个List<Contact> ,因此它必须是[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.我希望折叠结果集,以便所有具有相同(CCode、名称、地址)的条目都在一行中,并且我将在该行中将 OtherValue 连接到一个列表中。

I guess it's because int?我想这是因为int? is actually Nullable<int> and Nullable<T> doesn't implement IComparable .实际上是Nullable<int>并且Nullable<T>没有实现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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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