계층 구조 문제 -> 재귀를 LINQ 조인으로 대체 하시겠습니까?
-
07-07-2019 - |
문제
나는 자체 참조 테이블이 있는데, 여기에는 id, parentid (nullable)가 있습니다.
따라서 테이블에는 많은 노드가 포함되어 있거나 각 노드는 계층 구조 (부모는 NULL) 또는 계층의 모든 레벨 (부모가 테이블의 다른 곳에 존재 함)의 루트 일 수 있습니다.
임의의 시작 노드가 주어지면 해당 노드에서 계층 구조의 모든 어린이를 반환 할 우아한 LINQ 쿼리가 있습니까?
감사.
해결책
선택하려면 모든 직접적인 아이들 노드의 경우 다음과 같은 간단한 쿼리가 작업을 수행해야합니다.
from item in table
where item.ID == parentID;
select item
선택하려면 모든 후손 노드의 경우 LINQ에서는 불가능합니다. LINQ (및 SQL)가 제공하지 않는 재귀 또는 스택이 필요하기 때문입니다.
또한보십시오:
- 스택 오버플로: 자체 참조 테이블을 위해 LINQ에서 SQL?
- CodeProject : T -SQL- 계층 적 테이블에서 주어진 요소의 모든 후손을 얻는 방법
- 스택 오버플로: LINQ에서 재귀 표현
다른 팁
내가 방금 쓴 빠른 것입니다.
class MyTable
{
public int Id { get; set; }
public int? ParentId { get; set; }
public MyTable(int id, int? parentId) { this.Id = id; this.ParentId = parentId; }
}
List<MyTable> allTables = new List<MyTable> {
new MyTable(0, null),
new MyTable(1, 0),
new MyTable(2, 1)
};
Func<int, IEnumerable<MyTable>> f = null;
f = (id) =>
{
IEnumerable<MyTable> table = allTables.Where(t => t.Id == id);
if (allTables
.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).Count() != 0)
return table
.Union(f(
allTables.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).First().Id));
else return table;
};
그러나 나는 Union과 함께 SQL을 사용하는 것이 가능하다고 생각합니다.
나는 이것이 오래된 게시물이라는 것을 알고 있지만이 확장을 확인해야합니다.
http://www.scip.be/index.php?page=articlesnet23
나는 그것을 사용해 왔고 그것은 잘 작동하고 있습니다.
기본적으로 나는 당신이 제공 한 SO 링크에서 논의 된대로 이와 같은 것을 가지고 갈 것입니다.
public IQueryable GetCategories(Category parent)
{
var cats = (parent.Categories);
foreach (Category c in cats )
{
cats = cats .Concat(GetCategories(c));
}
return a;
}
CTE는 아마도 최상의 솔루션이지만 지금은 모든 것을 같은 계층으로 유지하고 싶습니다.
제휴하지 않습니다 StackOverflow