2011-05-04 4 views
1

여기에 질문을 게시하는 사람이 처음입니다. LINQ의 몇 가지 기능을 데모하려고하고 있으며 걸림돌을 맞았습니다. 다음 쿼리는 예상대로 작동하지 않을 :LINQ-to-Objects -이 간단한 복합 키 그룹의 문제점은 무엇입니까?

여기
Dim peopleByAgeAndName = _ 
    From p In (New PeopleRepository).GetAll 
    Group By key = New With {p.Age, p.Name} Into Group 
    Select Group 

은 매우 간단 PeopleRepository입니다 :

Public Class PeopleRepository 
    Public Function GetAll() As List(Of Person) 
     Dim people As New List(Of Person) 
     people.Add(New Person With {.Name = "Test Name #1", .Age = 33}) 
     people.Add(New Person With {.Name = "Test Name #1", .Age = 33}) 
     people.Add(New Person With {.Name = "Test Name #2", .Age = 0}) 
     people.Add(New Person With {.Name = "Test Name #3", .Age = 0}) 
     people.Add(New Person With {.Name = "Test Name #4", .Age = 0}) 
     people.Add(New Person With {.Name = "Test Name #5", .Age = 35}) 
     people.Add(New Person With {.Name = "Test Name #1", .Age = 39}) 
     Return people 
    End Function 
End Class 

그리고 여기에 더 간단한 Person 클래스입니다 : 이것은 분명히

Public Class Person 
    Property Name As String 
    Property Age As Integer 
End Class 

테스트 목적으로 모든 코드 설정. peopleByAgeAndName 쿼리를 실행 한 후에는 6 개의 그룹이 필요합니다. 각각은 "Test Name # 1"에 해당하는 그룹과 33 세의 Person 개체를 포함하고 있습니다. 비록 내가 뭘하든 관계없이 각각 하나의 요소로 구성된 7 개의 그룹이 있습니다.

의견이 있으십니까? 이것이 LINQ-to-Objects에 대해 정상적인 것인지 궁금합니다. 다시 말하지만, 모든 테스트 코드입니다. 나는 이것이 어떻게 작동하는지 더 잘 이해하려고 노력하고있다. 익명의 객체를 키로 사용할 때 그룹에 대해 속성 별 비교를 수행해야한다는 것을 이해했습니다. 나는 6 그룹이 아니라 7이되어야합니다.

고마워요!

var peopleByAgeAndName = 
     from p in peopleRepository.GetAll() 
     group p by new {p.Age, p.Name} into g 
     select g; 

내가 대신 7 6 개 그룹 나는 또한 그룹 키를 사용할 수 있음을 확인 얻을 : -

업데이트 기록을 위해

는 C#으로 다시 쿼리는 내가 예상 한대로 정확하게 수행 VB에서는 있지만 C#. 좀 이상 해요.

답변

0

아마도 Id를 기반으로하는 고유 한 개체를 제공하는 IEqualityComparer가 필요합니다.

+0

복합 키의 기준으로 사용자 정의 유형을 사용하고 있지만 익명 유형의 문자열을 사용하고 있기 때문에 Integer ...해야한다고 생각합니다. IEqualityCOmparer를 구현하십시오. 그것은 Person 객체를 전혀 비교하려고 시도해서는 안됩니다. 그냥 열쇠. –

0

그룹 키는 그룹화하려는 것입니다. 당신은 그룹을 혼합 선택하고 :

var grp=from p in persons 
     group p by p.Name into g 
     select new {g.Key, Ages=g}; 

그런 다음 당신이 이런 식으로 반복 것 :

foreach(var name in grp) 
{ 
    Console.WriteLine(name.Key); 

    foreach(var age in name) 
    Console.WriteLine(" "+age.Age); 
} 

이 비록 매우 단순하고, 더 나은 그룹이 될 것 같은 :

var grp=from p in persons 
     group p by p.Name into g 
     select new {Name=g.Key, Ages=from a in g 
            select a.Age}; 
+0

나는 당신의 권고를보고있다. 그러나 나는 그 결과가 내가하고 싶은 것을 할 것이라고 생각하지 않는다. 나는 기준 중 하나를 그룹화하고 하위 항목을 다른 대상으로 투영하려는 귀하의 생각을 이해합니다 ... 그러나 그룹화하려는 기준이 4 개 또는 5 개 또는 6 개라면 어떻게됩니까? 고유 키 (모든 키 값의 조합)로 그룹화되기를 원합니다 ...위의 데이터로 IEnumerable (IEnumerable (Of Person)) 개체가되고 결과적으로 6 개의 항목이 포함되어야하며 첫 번째 항목에는 2 개의 항목이 포함되고 나머지에는 각각 1 개의 항목이 포함되어야합니다. –

+0

또한, 문제는 내가 VB.Net에 대한 LINQ에 Group.Key가 없다는 것입니다. 아직 각 그룹의 열쇠를 얻는 방법을 찾지 못했습니다. 아마도 구문은 다르지만 group.key는 존재하지 않습니다. –

1

내 고의적 인 상황에 대한 해결책을 찾았습니다 ... Visual Basic에서 고유성을 결정하는 데 사용할 수있는 익명 형식의 속성에 "Key"특성을 추가해야합니다 :

Dim peopleByAgeAndName = _ 
    From p In (New PeopleRepository).GetAll 
    Group p By k = New With {Key p.Age, Key p.Name} Into g = Group 
    Select g 

지금은 매력처럼 작동합니다! 귀하의 조언을 주셔서 감사합니다!

+0

그룹 열을 참조하기 위해 g가 아닌 k를 참조해야한다는 것을 알게되었습니다. –

관련 문제