linq - 按匿名与分组分组按非匿名分组

标签 linq group-by

我需要在一些数据从服务器到达后对其进行分组。

var result = context.GetData();

Assert.Equal(54, result.Count); // OK

var transactions = result.GroupBy(t => new //BeneficiaryGroup
                        {
                            BankAcronym = t.BankAcronym.Substring(4, 4),
                            DebitDate = t.DebitDate,
                            Key = t.Key
                        })
                    .OrderBy(g => g.Key.BankAcronym)
                    .ThenBy(g => g.Key.DebitDate)
                    .ThenBy(g => g.Key.Key)
                    .ToList();

Assert.Equal( 14, transactions.Count ); // OK

当我按匿名对象分组时,分组是正确完成的。

当我按具有完全相同属性的 BeneficiaryGroup 对象分组时

public class BeneficiaryGroup 
{ 
    BankAcronym,
    DebitDate,
    Key
}

分组未正确完成 - 该组有 54 条记录,与分组前一样。

我想按类对数据进行分组,这样我就可以向 API 使用者返回一个已经分组的集合。

知道为什么会出现这种奇怪的行为吗?

最佳答案

匿名类型“免费”获得“明智的”相等行为,这就是分组在这种情况下按预期工作的原因。当您切换到使用命名类时,作为类定义者,您有责任提供相等行为,以允许 BeneficiaryGroup以您期望的方式用作分组键。


正如 the docs for GroupBy 中所说,

The default equality comparer Default is used to compare keys.

哪里Default EqualityComparer<T>.Default ,这解释了:

The Default property checks whether type T implements the System.IEquatable<T> interface and, if so, returns an EqualityComparer<T> that uses that implementation. Otherwise, it returns an EqualityComparer<T> that uses the overrides of Object.Equals and Object.GetHashCode provided by T.

for an anonymous type ,

Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashCode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.

而对于不会覆盖Equals的命名类型和 GetHashCode , 你会得到 Object实现,通常没有用。

关于linq - 按匿名与分组分组按非匿名分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35598386/

相关文章:

python - 使用转换计算数据框中的特定值和聚合结果

list - scala 对象列表,使用 groupBy 和平均值

MYSQL 过滤彼此相邻的相同行

c# - 如何通过 Linq 过滤一对多关系的查询

c# - 我是否遗漏了有关 LINQ 的信息?

c# - 如果在任何时候返回默认值,则停止 LINQ 查询

r - 如何快速将数据框中的时间列分组为间隔?

c# - 附加到表达式

c# - 无法将 'System.Int16' 类型的对象转换为 'System.String' 类型

sql - 为什么 Postgres Group By NULL 选择不计数?