2010-08-08 2 views
4

GroupBy를 사용하여 여러 하위 그리드에서 사용할 그룹의 계층 집합을 만듭니다.여러 그룹이 계층으로 구성된 GroupBy

6 개의 열, a, b, c, d, e, f가 포함 된 쿼리가 있다고 가정합니다.

이제 그룹별로 a, b, c, 다음으로 그룹화해야합니다. c의 그룹에서 전체 행을 반환합니다.

var q = rows.GroupBy(x => x.a) 

좋습니다. 저에게 제 그룹이 있습니다. 다음으로, 우리는 a와 b로 묶어 봅니다.

var q1 = q.Select(g =>new { 
    Key = g.Key, 
    SubGroup = g.GroupBy(x => x.b) 
} 

좋습니다. 괜찮습니다. b의 하위 그룹과 함께 a의 내 그룹을 얻습니다.

이제 세 번째 레벨에서 난처한 상황입니다. 다양한 구문을 시도했지만 대부분 컴파일되지 않습니다. 올바른 결과를주지는 않습니다.

var q2 = q1.Select(g1 => new { 
    Key = g1.Key, 
    SubGroup = g1.GroupBy(x => x.c) 
} 

이것은 컴파일되지 않습니다. g1에 GroupBy가 없다고 알려줍니다.

var q2 = q.Select(g1 => new { 
    Key = g1.Key, 
    SubGroup = g1.GroupBy(x => x.c) 
} 

이것은 b 하위 그룹이 아니며 a와 c 만 제공합니다.

내가 여기서 잘못하고있는 것에 대한 아이디어가 있습니까?

편집 : g1.Key 나는이 내부적으로 무엇을하고 있는지에 같은 가난한 파악이

var q2 = q.Select(g => new { 
    Key = g.Key, 
    SubGroup = g.Select(g1 => new { 
      Key = g1.Key 
      SubGroup = g1.GroupBy(a => a.c) 
     }) 

에 대한 정의가없는 말을

다음은 또한 작동하지 않습니다.

+0

그램이 단체의 단지 목록입니다 당신은 당신에게 개체를 제공 g.select 말을하는거야, 하지만 그 안에 열쇠가 없다. –

+0

네, 그걸 얻고 있습니다. 나는 여기에 점들을 연결하고 해결책이 무엇인지 알아 내지 못하고있다. –

답변

5

이제는 실제로 이것이 좋은 접근 방법이 아니라는 것을 말합니다. 느리게 진행될 것이고 올바른 작업을 수행하는 것이 성능에 중요한 경우 전체 컬렉션을 이러한 다양한 기준으로 정렬 한 다음 정렬 된 컬렉션의 다른 부분을 살펴 보는 것일 수 있습니다.

그러나 GroupByIGroupings을 사용하여 관리하려는 경우 잘못된 끝에서 작업하고있는 것입니다. 당신은 가장 깊은 수준에서 먼저 시작하여 일하고 싶습니다.

var groups = rows 
    .GroupBy(x => new { x.A, x.B, x.C, x.D, x.E, x.F }) 
    .GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C, x.Key.D, x.Key.E }) 
    .GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C, x.Key.D, }) 
    .GroupBy(x => new { x.Key.A, x.Key.B, x.Key.C }) 
    .GroupBy(x => new { x.Key.A, x.Key.B }) 
    .GroupBy(x => x.Key.A); 

groups.First().Key;    // will be an A value 
groups.First().First().First(); // will be an A, B, C group 
+0

이것은 내가 찾고있는 것에 매우 가깝고, 그렇게 느리지는 않습니다. 아마도이 작업을 할 수는 있지만 서브 그룹을 배수가 아닌 단일 열로 만 만들면 좋을 것입니다. –

+0

그래, 하위 그룹을 작동 시키려면 여러 필드가 필요한 것 같습니다. 너 다 남자 야! 당신이 여자가 아니라면, 당신은 여자 다! –

+0

보너스로, 그룹화를하기 전에 목록으로 Linq-to-SQL 쿼리를 변환하면 SQL 서버의 다중 쿼리가 아닌 메모리에서 수행되므로 훨씬 빠릅니다. 웹 서버에 약간의 부하를 추가하지만, 그것이 순수한 승리라고 생각합니다. –

2

GroupBy는 실제로 그룹화 할 요소 목록을 제공합니다. 각 그룹에는 동일한 처음 3 개 항목 (A, B & C)이 포함됩니다. .Key 메서드를 사용하여 키를 가져올 수 있으며 foreach를 사용하여 다른 행으로 재생할 수 있습니다. 예를 참조하십시오

var groups = Elements.GroupBy(x => new {x.A, x.B, x.C}); 
    foreach (var group in groups) 
    { 
     Trace.WriteLine(group.Key + ": " + group.Count()); 
     foreach (var row in group) 
     { 
      Trace.WriteLine(row.D); 
     } 
    } 

편집 : - 아, 괜찮아 당신이 필요로하는 것은이 다음입니다 :

var groups = Elements 
     .GroupBy(a => new {a.A}) 
     .Select(g1 => new { 
      A = g1.Key, 
      Groups = g1 
      .GroupBy(b=> new {b.B}) 
      .Select(g2 => new { 
       B = g2.Key, 
       Groups = g2 
       .GroupBy(c => new {c.C}) 
       .Select(g3 => new { 
        C = g3.Key, 
        Rows = g3 
       }) 
      }) 
     }); 

    foreach (var groupA in groups) 
    { 
     Trace.WriteLine(groupA.A); 
     foreach (var groupB in groupA.Groups) 
     { 
      Trace.WriteLine("\t" + groupB.B); 
      foreach (var groupC in groupB.Groups) 
      { 
       Trace.WriteLine("\t\t" + groupC.C); 
       foreach (var row in groupC.Rows) 
       { 
        Trace.WriteLine("Row: " + row.ToString()); 
       } 
      } 
     } 
    } 
+0

아니요, a, b 및 c를 사용하여 하나의 그룹을 만듭니다. 각각의 모음이 아닙니다. –

+0

Ok - 당신을 위해 그룹을 중첩하도록 변경했습니다. 과도한 중첩/여러 필드 등을 모두 수행 할 필요가 없기 때문에 다른 답변보다 뛰어납니다. –

+0

예, 원래 원래 시도하려고했던 곳이었습니다. , 나는 이제 내가 잘못한 것을 봅니다. 그러나, mquander의 반응은 실제로 내가하고있는 것보다 내가하는 것이 더 의미가 있습니다. 그 이유는 하이라이팅의 모든 객체가 그룹핑과 IOrderedQueryable의 혼합이 아니라 IGroupings이기 때문입니다. 이것은 당신의 솔루션이하는 것입니다. 하지만 +1 할게. –