2011-04-06 5 views
0

2 개의 서로 다른 시스템에서 비슷한 데이터를 2 개 표현했으며 한 시스템의 각 엔티티와 다른 엔티티를 대응시켜야합니다. 내가해야 할 일은 기본적으로VB.NET LINQ - 계층 적 데이터를 플랫 데이터와 일치시키기

- { 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 } 

그리고 : 같은 것을 찾고 List(Of CategoryB)로 표현, 평평

- "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 :

시스템 A는 Dictionary(Of String, List(Of CategoryA)) 찾고 뭔가 등으로 표현, 계층입니다 조직 이름 (Dictionary.Key ~ CategoryB.Org)과 범주 이름 (CategoryA.Name ~ 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 

내가 그것을 조직 속성을 적용 할 수 있도록 CategoryA 개체에 액세스 할 수없는, 또는 내가 할 것이며이 쉽게 나 자신에. Dictionary 키와 그 값에있는 항목 중 하나의 속성에 참여하는 방법을 알아낼 수 없으므로 유용한 정보로 끝납니다. 내가 만든 가장 성공적인 구현은 먼저 For Each 루프를 포함하고, 내부에 LINQ 쿼리 :

Given: 
    catA = Dictionary(Of String, List(Of CategoryA)) 
    catB = List(Of CategoryB) 

Dim result As New Dictionary(Of String, List(Of Tuple(Of CategoryA, CategoryB))) 

For Each kvp As KeyValuePair(Of String, List(Of CategoryA)) In catA 
    Dim orgName As String = kvp.Key 

    If Not result.ContainsKey(orgName) Then 
     result.Add(orgName, New List(Of Tuple(Of CategoryA, CategoryB))) 
    End If 

    Dim orgCategories As IEnumerable(Of CategoryB) = 
     From cat In catB Where cat.Org = orgName 

    Dim tmpResult As IEnumerable(Of Tuple(Of CategoryA, CategoryB)) = 
     From cat_a In kvp.Value 
     Group Join cat_b In orgCategories 
      On cat_a.Name Equals cat_b.Name 
     Into matchedCats = Group 
     From cat In matchedCats.DefaultIfEmpty 
     Select matches = Tuple.Create(cat_a, cat) 

    result(orgName).AddRange(tmpResult) 
Next 

그것은 확실히 작동하지만, 나는 그것이 같은 성명에서 싶습니다.

답변

0

글쎄,이 다소 작동하지만 ID는 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 
관련 문제