2011-06-10 3 views
9

이 문제는 많은 시간을 보냈습니다.VB.Net에서 여러 속성을 사용하는 LINQ 그룹

dim lFinal={new with {.Year=2010, .Month=6, .Value1=0, .Value2=0}, 
      new with {.Year=2010, .Month=6, .Value1=2, .Value2=1}, 
      new with {.Year=2010, .Month=7, .Value1=3, .Value2=4}, 
      new with {.Year=2010, .Month=8, .Value1=0, .Value2=1}, 
      new with {.Year=2011, .Month=1, .Value1=2, .Value2=2}, 
      new with {.Year=2011, .Month=1, .Value1=0, .Value2=0}} 

Dim lFinal2 = From el In lFinal 
       Group el By Key = new with {el.Year,el.Month} 
       Into Group 
       Select New With {.Year = Key.Year, .Month=Key.Month, .Value1 = Group.Sum(Function(x) x.Value1), .Value2 = Group.Sum(Function(x) x.Value2)} 

lFinal.Dump() 
lFinal2.Dump() 

lFinal을 : 나는 (하나 개의 속성에) LINQ 쿼리에 의해 간단하게 그룹을 할 수 있어요하지만 여러 필드에 내가 조금 붙어있어 ... 여기 내가 뭘 원하는지의 LINQPad 샘플입니다 목록에 6 개의 항목이 있습니다. lFinal2에 4 개의 항목이 있어야합니다. 2010-6 및 2011-1이 그룹이어야합니다.

미리 감사드립니다.

+0

d를 작동 시키려면 GetHashCode()를 구현하십시오. – Maher

답변

4

100 % 확실하지만 그룹 아마도이 같음을 사용하여() 및/또는 GetHashCode하지 구현, 그래서 당신이 내재적으로 작성 수행 할 때

= Group el By Key = new with {el.Year,el.Month} 

가 내장 객체 모두 올해 확인할 모르는 및 월 (속성이 있기 때문에 다른 개체와 비교할 때 체크하지는 않습니다).

그래서 당신은 아마 이런 일을 수행해야합니다 :

= Group el By Key = new CustomKey() { Year = el.Year, Month = el.Month }; 

public class CustomKey{ 
    int Year { get; set; } 
    int Month { get; set; } 

    public override bool Equals(obj A) { 
     var key (CustomKey)A; 
     return key.Year == this.Year && key.Month == this.Month; 
    } 
} 
+0

+1. OP 구문은 LINQ-to-SQL에서 잘 작동하지만 LINQ-to-Objects에서 사용할 때 현재 출력을 생성합니다. –

+1

+0 이것이 맞지만 'Key'키워드가 정답입니다. –

5

감사합니다! 하지만 작동하도록 GetHashCode 함수를 작성해야한다는 것을 알았습니다.

클래스 :

Public Class YearMonth 
    Implements IEquatable(Of YearMonth) 

    Public Property Year As Integer 
    Public Property Month As Integer 

    Public Function Equals1(other As YearMonth) As Boolean Implements System.IEquatable(Of YearMonth).Equals 
     Return other.Year = Me.Year And other.Month = Me.Month 
    End Function 

    Public Overrides Function GetHashCode() As Integer 
     Return Me.Year * 1000 + Me.Month * 100 
    End Function 
End Class 

그리고 LINQ 쿼리 :

Dim lFinal2 = From el In lFinal 
       Group el By Key = New YearMonth With {.Year = el.Year, .Month = el.Month} 
       Into Group 
       Select New ItemsByDates With {.Year = Key.Year, 
              .Month = Key.Month, 
              .Value1 = Group.Sum(Function(x) x.Value1), 
              .Value2 = Group.Sum(Function(x) x.Value2)} 
+1

+0 이것이 맞지만 'Key'키워드가 정답입니다. –

18

은을 사용하여 익명 형식의 속성은 불변 확인 나는 VB.Net의 최종 클래스 + LINQ GROUPBY의 번역을 제공 Key 키워드를 사용하면 비교에 사용됩니다.

Dim lFinal2 = From el In lFinal    
    Group el By Key = new with {key el.Year, key el.Month} 
    Into Group 
    Select New With { 
      .Year = Key.Year, 
      .Month = Key.Month, 
      .Value1 = Group.Sum(Function(x) x.Value1), 
      .Value2 = Group.Sum(Function(x) x.Value2) 
    }