2014-03-27 94 views
1

我下面的數據的GroupBy與使用LINQ

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

我想組數據由Id1Id2使用LINQ 當我通過如下它給了我正確的結果做組預定義類型

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

如何用預定義類型實現相同的結果?

+1

如果您打算爲此使用該對象,您應該使其不可變。可變的哈希表鍵是...不可取的。 – Servy

+0

我想你需要重寫equals,如果你打算使用你自己的類型進行分組。 –

+0

如果您使用該類_only_進行分組,那麼您會發現使用匿名類型更容易,維護也更少。 –

回答

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的實施方面中定義的原因在匿名類型上定義的屬性(請參閱MSDN上「Anonymous Types」文章中的「備註」部分)。

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

首先,它比內存需要更少的內存。其次,默認的結構相等行爲比較結構的內容而不是引用。這就是爲什麼它沒有正確分組。

+0

我得到了這個錯誤'錯誤自動實現的屬性GroupKey.id1'的備份字段必須在控制返回給調用者之前完全分配。考慮從構造函數初始值設定項中調用默認構造函數。 \t' –

+0

@gmailuser固定。注意添加this() – Euphoric