[英]Exception when using LINQ orderby: "Failed to compare two elements in the array"
以下是重现异常的示例代码:
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)
{
}
}
}
}
执行此程序时,执行到foreach (var group in q)
时抛出异常:
System.InvalidOperationException:“无法比较数组中的两个元素。”
内部异常
ArgumentException:至少一个 object 必须实现 IComparable
我已经查看了有关尝试对列表进行排序时出现的此错误消息的其他 SO 问题; 但在这段代码中我不确定哪个操作需要比较器。 似乎orderby g.Key
操作可能需要比较组中的匿名 class,但是匿名 class 不应该有默认比较器吗? 或者,如果没有,我不确定将代码放在哪里来实现它。
令人困惑的是,如果我用新行将i.CCode
从group i by new
中取出,那么异常就不会再发生了。
背景:我的真实项目是一个使用 EFCore 6 的 Blazor 应用程序,并且正在从存储过程结果中接收到一个List<Contact>
,因此它必须是[Keyless]
。 我必须使用未修改的现有存储过程,因此我在我的代码中执行结果转换。 我希望折叠结果集,以便所有具有相同(CCode、名称、地址)的条目都在一行中,并且我将在该行中将 OtherValue 连接到一个列表中。
我想这是因为int?
实际上是Nullable<int>
并且Nullable<T>
没有实现IComparable
。 我刚刚测试了您的代码,但将分组更改为:
group i by new { CCode = i.CCode.HasValue ? i.CCode.Value : (int?)null, i.Name, i.Address } into g
它似乎起作用了。 至少它没有抛出那个异常。
匿名类型没有比较器,通过属性指定顺序:
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.