VB.NET LINQ - 将分层数据与平面数据匹配

时间:2011-04-06 18:11:36

标签: vb.net linq

我有2个来自2个不同系统的类似数据的表示,我需要将一个系统中的每个实体与另一个系统中的实体相匹配。

系统A是分层的,表示为Dictionary(Of String, List(Of CategoryA)),类似于:

- "Organization 1" 
    - { Name = "Cat1", Id = 1}
    - { Name = "Cat2", Id = 2}
    - { Name = "Cat3", Id = 3}

- "Organization 2" 
    - { Name = "Cat1", Id = 4}
    - { Name = "Cat3", Id = 5}
    - { Name = "Cat4", Id = 6}

- "Organization 3" 
    - { Name = "Cat1", Id = 7}
    - { Name = "Cat2", Id = 8}
    - { Name = "Cat3", Id = 9}
    - { Name = "Cat4", Id = 10}

系统B是Flattened,表示为List(Of CategoryB),类似于:

- { Org = "Organization 1", Name = "Cat1", Id = 100 }
- { Org = "Organization 1", Name = "Cat2", Id = 101 }
- { Org = "Organization 1", Name = "Cat3", Id = 102 }

- { Org = "Organization 2", Name = "Cat1", Id = 103 }
- { Org = "Organization 2", Name = "Cat2", Id = 104 }
- { Org = "Organization 2", Name = "Cat4", Id = 105 }

- { Org = "Organization 4", Name = "Cat1", Id = 106 }
- { Org = "Organization 4", Name = "Cat2", Id = 107 }
- { Org = "Organization 4", Name = "Cat3", Id = 108 }
- { Org = "Organization 4", Name = "Cat4", Id = 109 }

基本上我需要做的是将分层数据外部加入到组织名称(Dictionary.KeyCategoryB.Org)和类别名称(CategoryA.Name到{{1}的扁平数据上}}),给我一个CategoryB.Name或类似的东西:

Dictionary(Of String, IEnumerable(Of Tuple(Of CategoryA, CategoryB)))

我无法访问- "Organization 1" - { Name = "Cat1", Id = 1}, { Org = "Organization 1", Name = "Cat1", Id = 100 } - { Name = "Cat2", Id = 2}, { Org = "Organization 1", Name = "Cat2", Id = 101 } - { Name = "Cat3", Id = 3}, { Org = "Organization 1", Name = "Cat3", Id = 102 } - "Organization 2" - { Name = "Cat1", Id = 4}, { Org = "Organization 2", Name = "Cat1", Id = 103 } - { Name = "Cat3", Id = 5}, null - { Name = "Cat4", Id = 6}, { Org = "Organization 2", Name = "Cat4", Id = 105 } - "Organization 3" - { Name = "Cat1", Id = 7}, null - { Name = "Cat2", Id = 8}, null - { Name = "Cat3", Id = 9}, null - { Name = "Cat4", Id = 10}, null 对象以便能够将组织属性应用于它,或者我会这样做并使自己更容易。我只是无法弄清楚如何加入Dictionary键和其值中的一个项的属性,并最终得到任何有用的东西。我创建的最成功的实现首先涉及CategoryA循环,内部有一个LINQ查询:

For Each

它运作正常,但我希望它在同一个声明中。

1 个答案:

答案 0 :(得分:0)

嗯,这种方法很有效,但是你会坚持使用你的for循环!

Public Class CategoryA
    Public Property Name As String
    Public Property Id As Integer
End Class

Public Class CategoryB
    Public Property Org As String
    Public Property Name As String
    Public Property Id As Integer
End Class

Private SystemA As New Dictionary(Of String, List(Of CategoryA))
Private SystemB As New List(Of CategoryB)

Sub Main()
    SystemA.Add("Org1", New List(Of CategoryA) From {New CategoryA() With {.Id = 1, .Name = "Cat1"},
                                                     New CategoryA() With {.Id = 2, .Name = "Cat2"},
                                                     New CategoryA() With {.Id = 3, .Name = "Cat3"}})
    SystemA.Add("Org2", New List(Of CategoryA) From {New CategoryA() With {.Id = 4, .Name = "Cat1"},
                                                     New CategoryA() With {.Id = 5, .Name = "Cat2"},
                                                     New CategoryA() With {.Id = 6, .Name = "Cat3"}})
    SystemA.Add("Org3", New List(Of CategoryA) From {New CategoryA() With {.Id = 7, .Name = "Cat1"},
                                                     New CategoryA() With {.Id = 8, .Name = "Cat2"},
                                                     New CategoryA() With {.Id = 9, .Name = "Cat3"},
                                                     New CategoryA() With {.Id = 10, .Name = "Cat4"}})

    SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat1", .Id = 100})
    SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat2", .Id = 101})
    SystemB.Add(New CategoryB() With {.Org = "Org1", .Name = "Cat3", .Id = 102})
    SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat1", .Id = 103})
    SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat2", .Id = 104})
    SystemB.Add(New CategoryB() With {.Org = "Org2", .Name = "Cat4", .Id = 105})
    SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat1", .Id = 106})
    SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat2", .Id = 107})
    SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat3", .Id = 108})
    SystemB.Add(New CategoryB() With {.Org = "Org4", .Name = "Cat4", .Id = 109})


    Dim AllOrgs = SystemA.Keys.Union(SystemB.Select(Function(b) b.Org).Distinct)

    Dim BothCats2 = From org In AllOrgs
                    Let CatAList = If(Not SystemA.ContainsKey(org), New List(Of CategoryA), From cat In SystemA(org))
                    Let CatBList = (From cat In SystemB Where cat.Org = org).ToList
                    Let AllCatNames = (From cat In CatAList Select cat.Name Distinct).Union(From cat In CatBList Select cat.Name Distinct)
                    Let BothCats = (From cat In AllCatNames
                                    From A In CatAList.Where(Function(CatA) CatA.Name = cat).DefaultIfEmpty
                                    From B In CatBList.Where(Function(CatB) CatB.Name = cat).DefaultIfEmpty)
                    Select org, BothCats

End Sub