Linq to Sql - 查找祖先的分层查询
-
04-07-2019 - |
题
给定一个EmployeeId,我如何构建一个Linq to Sql查询来查找该员工的所有祖先?每个EmployeeId都有一个相关的SupervisorId(见下文)。
例如,对EmployeeId 6(Frank Black)的祖先的查询应该返回Jane Doe,Bob Smith,Joe Bloggs和Head Honcho。
如有必要,我可以缓存所有员工的名单以提高绩效。
<强>更新强>
我已经创建了以下原始方法来完成任务。它遍历employee.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 Extension Methods项目中使用分层查询。我认为可能有助于简化您的代码。
这里的问题是,这将为层次结构中的每个节点创建一个数据库调用。在您的示例中,您将有5次往返数据库。
我将使用不同的路径并创建一个存储过程来为我执行此操作并返回整组 Employee
对象。由于在返回对象之前断开对象(处理上下文),您只需从存储过程的结果集中创建新对象。
其他提示
避免加载整个Employee表(但遍历深度有限)的简单解决方案是......
var emps = dc.Employees.Where(e => (e.EmployeeId == EmployeeId) ||
(e.SupervisorId == EmployeeId) ||
(e.Supervisor.SupervisorId == EmployeeId) ||
(e.Supervisor.Supervisor.SupervisorId == EmployeeId) ||
...);
最终,您应该使用公用表格表达式来展平层次结构,但LINQ to SQL目前不支持此功能。您可以考虑编写自己的扩展方法(如Omer库中的那个,但使用IQueryable而不是IEnumerable来支持服务器端执行)。
不隶属于 StackOverflow