4

EmployeeId が与えられた場合、Linq to Sql クエリを作成して従業員の先祖をすべて見つけるにはどうすればよいですか? 各 EmployeeId には、関連付けられた SupervisorId があります (以下を参照)。

たとえば、EmployeeId 6 (Frank Black) の祖先のクエリは、Jane Doe、Bob Smith、Joe Bloggs、および Head Honcho を返す必要があります。

必要に応じて、すべての従業員のリストをキャッシュして、パフォーマンスを向上させることができます。

アップデート:

タスクを達成するために、次の大まかなメソッドを作成しました。これは、employee.Supervisor 関係をルート ノードまでたどります。ただし、これは従業員ごとに 1 つのデータベース呼び出しを発行します。より簡潔またはよりパフォーマンスの高い方法を持っている人はいますか? ありがとう。

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 のライブラリにあるものと同様ですが、サーバー側の実行をサポートするために IEnumerable の代わりに IQueryable を使用します)。

于 2008-10-27T11:29:20.293 に答える