2013-04-23 2 views
1

다음과 같이 계층 구조가있는 데이터 구조가 있습니다.Linq가 계층을 통해 반복됩니다.

TABLE 1

id | Groupname | parentId 

TABLE 1 parentId는 표 1의 ID를 참조 2

id | nodeName | parentId 

표 및 표 2 parentId 또한 표 1 ID를 말한다.

표 1의 ID부터 시작하여 모든 노드를 출력 한 다음 모든 하위 그룹의 하위 노드를 통과해야합니다.

은 지금까지 나는이

int id = 1; // replace with argument 

repository.Nodes.Where(n => n.ParentId == Id).ToList().ForEach(d => 
{ 
    result.NodeList.Add(GetNodeDetails(n.Id)); 
}); 

사람이 나를 도와 수있는이 좋은 efficent의 LINQ 방식을 통해 반복?

+0

계층 구조를 병합하려면 원하는가요? –

+0

노드의 하위 노드는 어떻게 구합니까? 내비게이션 속성이 있습니까? –

+0

예 평평하게하고 싶습니다. 예, 탐색 속성이 있습니다. 감사. – DavidB

답변

5

정확하게 이해하면 계층 구조를 병합하려는 것입니다. 즉, 최종 결과는 모든 계층 구조 수준의 모든 하위 항목이 포함 된 단일 목록이어야합니다.

이를 달성하는 가장 간단한 방법은 재귀 통해 :

private IEnumerable<Node> GetSelfAndChildren(Node node) 
{ 
    yield return GetNodeDetails(n.Id); 
    foreach(var c in n.Children.SelectMany(GetSelfAndChildren) 
     yield return c; 
}; 


var result = repository.Nodes.Where(n => n.ParentId == Id) 
         .AsEnumerable() 
         .SelectMany(GetSelfAndChildren) 
         .ToList(); 

이 아이들의 단순 목록을 얻기 위해 재귀 적 방법을 사용합니다.

이 접근법은 N + 1 문제를 나타낼 가능성이 있습니다. 구성에 따라 Children의 각 액세스는 데이터베이스로 왕복 할 수 있습니다.
N + 1 문제가 발생하여 문제가 발생하는 경우 다른 방법은 먼저 노드를 데이터베이스에서 가져온 다음 Breadth-first search을 수행하는 것입니다.

+0

Daniel, Ill 감사합니다. – DavidB

+0

재귀를 통해서만 달성 할 수 있다고 말하면 루프없이 완료된다는 제한이 있습니까? 또한 'yield return'을 사용하여 +1하기 때문에 마침내 사용하기 시작합니다. – rliu

+1

@roliu : 내가 무엇을 요구하는지 잘 모르겠습니다. 내 코드에는 분명히 루프가 있습니다. 그러나 루프만으로는 달성 할 수 없습니다. 적어도 쉽지는 않습니다. –

관련 문제