LINQ에서 SQL- 조상을 찾기 위해 계층 적 쿼리
-
04-07-2019 - |
문제
EmployeeId가 주어지면 어떻게 직원의 조상을 찾기 위해 LINQ에서 SQL 쿼리를 어떻게 구성 할 수 있습니까? 각 직원은 관련 SupervisorID가 있습니다 (아래 참조).
예를 들어, Employeeid 6 (Frank Black)의 조상 쿼리는 Jane Doe, Bob Smith, Joe Bloggs 및 Head Honcho를 반환해야합니다.
필요한 경우 모든 직원의 목록을 캐시하여 성과를 향상시킬 수 있습니다.
업데이트:
작업을 수행하기 위해 다음 원유 방법을 만들었습니다. 그것은 직원을 가로 지릅니다. Supervisor 관계는 루트 노드까지입니다. 그러나 이렇게하면 각 직원마다 하나의 데이터베이스 호출이 발행됩니다. 더 간결하거나 성능이있는 방법이 있습니까? 감사.
private List<Employee> GetAncestors(int EmployeeId)
{
List<Employee> emps = new List<Employee>();
using (L2STestDataContext dc = new L2STestDataContext())
{
Employee emp = dc.Employees.FirstOrDefault(p => p.EmployeeId == EmployeeId);
if (emp != null)
{
while (emp.Supervisor != null)
{
emps.Add(emp.Supervisor);
emp = emp.Supervisor;
}
}
}
return emps;
}
해결책
우선, 당신은 내에서 계층 적 쿼리를 사용할 수 있습니다. LINQ 확장 방법 프로젝트. 코드를 단순화하는 데 도움이 될 수 있다고 생각합니다.
여기서 문제는 이것이 계층 구조의 각 노드에 대한 데이터베이스 호출을 생성한다는 것입니다. 예제의 경우 데이터베이스에 5 번의 왕복이 있습니다.
나는 다른 길을 가고 저를 위해 저장된 절차를 만들고 전체 세트를 반환합니다. Employee
사물. 객체를 반환하기 전에 객체를 연결 해제하기 때문에 (컨텍스트를 처분) 저장된 프로 시저의 결과 세트에서 새 개체를 만들 수 있습니다.
다른 팁
전체 직원 테이블을로드하는 것을 피하는 간단한 솔루션 (트래버스 깊이는 제한적입니다)은 ...
var emps = dc.Employees.Where(e => (e.EmployeeId == EmployeeId) ||
(e.SupervisorId == EmployeeId) ||
(e.Supervisor.SupervisorId == EmployeeId) ||
(e.Supervisor.Supervisor.SupervisorId == EmployeeId) ||
...);
궁극적으로 사용해야합니다 일반적인 테이블 표현 계층 구조를 평평하게하려면 LINQ에서 SQL이 현재 지원하지 않습니다. Omer의 라이브러리에있는 것과 같이 자신의 확장 방법을 작성할 수 있지만 서버 측 실행을 지원하기 위해 ienumerable 대신 iqueryable을 사용하는 방법을 살펴볼 수 있습니다.