GroupBy使用Linq预定义类型

时间:2014-03-27 17:20:43

标签: c# .net linq

我关注数据

 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; }
    }    

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

2 个答案:

答案 0 :(得分:4)

为类型实施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的实现,这些实现是根据定义的属性定义的在匿名类型上(请参阅&#34;备注&#34;有关MSDN上&#34; Anonymous Types&#34;文章的部分)。

答案 1 :(得分:1)

使用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; }
} 

首先,它需要的内存少于类。第二,默认的结构相等行为比较结构的内容而不是引用。这就是为什么它没有正确分组。