使用Linq预定义类型的GroupBy

本文关键字:GroupBy 类型 预定义 Linq 使用 | 更新日期: 2023-09-27 17:54:01

我有以下数据

 Id1      Id2        Days
 ------------------------
  1        1          10
  1        1          20
  1        2          30
  1        3          40

我想使用Linq按Id1Id2对数据进行分组当我按照下面的方式分组时,它会给我正确的结果

List<data>.GroupBy(p => new {p.Id1, p.Id2});

但当我使用预定义的类型时,它会将结果作为四个不同的行组。它不会将前两行合并为一组。

List<data>.GroupBy(p => new GroupKey(p.Id1, p.Id2));
    class GroupKey
    {
        public GroupKey(decimal _id1,decimal _id2)
        {
            Id1= _id1;
            Id2= _id2;
        }
        public decimal Id1{ get; set; }
        public decimal Id2{ get; set; }
    }    

如何使用预定义类型实现相同的结果?

使用Linq预定义类型的GroupBy

为类型实现EqualsGetHashCode

类似于:

public override bool Equals(object other)
{
    var otherKey = other as GroupKey;
    if (otherKey == null)
    {
        return false;
    }
    return otherKey.Id1 == this.Id1 && otherKey.Id2 == this.Id2;
}
public override int GetHashCode()
{
    return this.Id1.GetHashCode() ^ this.Id2.GetHashCode();
}

这适用于匿名类型(如您在第一个示例中创建的类型(的原因是,匿名类型会自动获得根据匿名类型上定义的属性定义的EqualsGetHashCode的实现(请参阅MSDN上"匿名类型"文章的"备注"部分(。

使用struct而不是class并使其不可变。

struct GroupKey
{
    public GroupKey(decimal _id1,decimal _id2):this()
    {
        Id1= _id1;
        Id2= _id2;
    }
    public decimal Id1{ get; private set; }
    public decimal Id2{ get; private set; }
} 

首先,它占用的内存将少于课堂。其次,默认的结构相等行为比较结构和非引用的内容。这就是为什么它没有正确分组。