4

给定一个 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;
}
4

2 回答 2

1

首先,欢迎您在我的LINQ 扩展方法项目中使用分层查询。我认为可能有助于简化您的代码。

这里的问题是这将为层次结构中的每个节点创建一个数据库调用。在您的示例中,您将有 5 次往返数据库。

我会走一条不同的路并创建一个存储过程来为我做这件事并返回整个Employee对象集。由于您在返回对象(处理上下文)之前断开了对象的连接,因此您可以简单地从存储过程的结果集中创建新对象。

于 2008-10-25T22:03:15.723 回答
1

避免加载整个 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 来支持服务器端执行)。

于 2008-10-27T11:29:20.293 回答