Linq - How to convert from flat to hierarchical?

Var result = from eachData in data group eachData by new{ eachData . G1_ID, eachData . G1_CellName } into g1 from eachG1 in g1 group eachG1 by new { eachG1.

G2_..., eachG1. G2_... } into g2 for eachG2 in g2 group eachG2 by new { eachG2. G3_... } into g3 select g3 haven't test it.

But i'm sure its gonna look just like this.

Var result = from eachData in data group eachData by new{ eachData . G1_ID, eachData . G1_CellName } into g1 from eachG1 in g1 group eachG1 by new { eachG1.

G2_..., eachG1. G2_... } into g2 for eachG2 in g2 group eachG2 by new { eachG2. G3_... } into g3 select g3; haven't test it.

But i'm sure its gonna look just like this.

I had considered GroupBy, but that wouldn't produce the collections of g2 and g3 data grouped into each g1 element. I think you have to make 3 passes on the original list, but maybe I'm wrong :) – Tom Nov 30 '10 at 8:15.

Ok, this is quite a through provoking question. I've done a lot of data flattening in the past, and typically I'd use a Dictionary to keep all the unique values, then marry them up afterwards. You asked for LINQ, now I cannot think of a single-pass way to do this, so I've got this instead, in VB... Private Class FlatObj Public Property G1_ID As Integer Public Property G1_CellName As String Public Property G2_ContainerID As Integer Public Property G2_ID As Integer Public Property G2_SerialNumber As Integer Public Property G3_ID As Integer Public Property G3_PrinterName As String End Class Private Class G1 Public Property ID As Integer Public Property CellName As String Public Property Containers As New List(Of G2)() Public Property PrinterNames As New List(Of G3)() Public Overrides Function Equals(ByVal obj As Object) As Boolean Return ID.

Equals(CType(obj, G1). ID) End Function Public Overrides Function GetHashCode() As Integer Return ID.GetHashCode() End Function End Class Private Class G2 Public Property fID As Integer Public Property ContainerID As Integer Public Property SerialNumber As Integer Public Overrides Function Equals(ByVal obj As Object) As Boolean Return ContainerID. Equals(CType(obj, G2).

ContainerID) End Function Public Overrides Function GetHashCode() As Integer Return ContainerID.GetHashCode() End Function End Class Private Class G3 Public Property fID As Integer Public Property PrinterName As String Public Overrides Function Equals(ByVal obj As Object) As Boolean Return PrinterName. Equals(CType(obj, G3). PrinterName) End Function Public Overrides Function GetHashCode() As Integer Return PrinterName.GetHashCode() End Function End Class Dim fromDb As New List(Of FlatObj) From { New FlatObj() With {.

G1_ID = 1971, . G1_CellName = "Default Cell", . G2_ContainerID = 1935, .

G2_ID = 1971, . G2_SerialNumber = 1101929, . G3_ID = 1971, .

G3_PrinterName = "PBG-PrtEmulator1"}, New FlatObj() With {. G1_ID = 1971, . G1_CellName = "Default Cell", .

G2_ContainerID = 1936, . G2_ID = 1971, . G2_SerialNumber = 1101930, .

G3_ID = 1971, . G3_PrinterName = "PBG-PrtEmulator1"}, New FlatObj() With {. G1_ID = 1971, .

G1_CellName = "Default Cell", . G2_ContainerID = 2189, . G2_ID = 1971, .

G2_SerialNumber = 1102183, . G3_ID = 1971, . G3_PrinterName = "PBG-PrtEmulator1"} } Dim g1s = fromDb.

Select(Function(x) New G1 With { . ID = x. G1_ID, .

CellName = x. G1_CellName }).Distinct().ToList() Dim g2s = fromDb. Select(Function(x) New G2 With { .

FID = x. G2_ID, . ContainerID = x.

G2_ContainerID, . SerialNumber = x. G2_SerialNumber }).Distinct().

ToLookup(Function(x) x. FID) Dim g3s = fromDb. Select(Function(x) New G3 With { .

FID = x. G3_ID, . PrinterName = x.

G3_PrinterName }).Distinct(). ToLookup(Function(x) x. FID) g1s.

ForEach(Sub(g) g.Containers. AddRange(g2s(g. ID)) g.PrinterNames.

AddRange(g3s(g. ID)) End Sub) Notice that quite a lot of the work has gone through the Distinct() and ToLookup() extensions. Hope this helps, I'd like to see if there is a more "LINQy" way :D.

New FlatObj() With {. G1_ID = 1971, . G1_CellName = "Default Cell", .

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions