2010-11-29 19 views
5

Bir Linq sorgusunun sonucu olarak oluşturulan aşağıdaki sonuç kümesine sahibim. Bunu bir hiyerarşik sonuç kümesine dönüştürmek istiyorum. İlk iki sütun 'ana' satırı temsil edecek, sütunlar 3 ve 4 ana satırın bir alt listesini temsil edecek ve sütun 5 ve 6 ana satırın ikinci bir alt listesini temsil edecektir. 1971 değerini içeren sütunlar birleştirme sütunlarıdır.Linq - Düzden hiyerarşiye nasıl dönüştürülür?

Sonuç, bir kapsayıcı listesi (G2 sütunları) ve bir yazıcı listesi (G3 sütunları) içeren bir ana nesne olmalıdır.

Sorgu, hiyerarşik forma dönüştürmek için ne gibi görünüyor?

G1_ID G1_CellName G2_ContainerID G2_ID G2_SerialNumber G3_ID  G3_PrinterName 
1971 Default Cell 1935   1971 1101929   1971  PBG-PrtEmulator1 
1971 Default Cell 1936   1971 1101930   1971  PBG-PrtEmulator1 
1971 Default Cell 2189   1971 1102183   1971  PBG-PrtEmulator1 
+0

Sadece netleştirmek için ... Sen nesne gibi görünür bir hiyerarşi istiyor? – Tom

+0

Bu Linq to Sql, Linq to EF, Linq nesnelere veya başka bir şeye mi? –

+0

@Tom - Cell -> Cell.Containers ve Cell -> PrinterNames gibi görünen bir hiyerarşi istiyorum. Seri numarası sütunu, Konteynerin bir özelliğidir. –

cevap

2

groupby?

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; 

bunu test değil. ama eminim bunun gibi görünecek. Cell> Cell.Containers, Cell.SerialNumbers, Cell.PrinterNames ile (koleksiyonları gibi) -

+0

Ben GroupBy kabul ediyorum, ama bu g2 ve her g1 eleman halinde gruplandırılmış g3 verilerin koleksiyonları üretmek olmaz. Ben orijinal listedeki 3 geçer yapmak zorunda düşünüyorum, ama belki de yanılıyorum :) – Tom

1

Tamam, bu oldukça provoke edici bir sorudur. Geçmişte çok fazla veri düzleştirmesi yaptım ve tipik olarak tüm benzersiz değerleri saklamak için bir Sözlük kullandım, daha sonra onları evlendirdim.

Artık bunu yapmak için tek geçişli bir şekilde düşünemiyorum, LINQ istedi, bu yüzden ... VB, onun yerine bu var

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) 

Bildirimi o ettik oldukça çok çalışma Distinct() ve ToLookup() uzantıları üzerinden geçti. Umarım bu yardımcı olur, daha fazla "LINQy" yolu olup olmadığını görmek isterim: D

İlgili konular