Domanda

Dato un EmployeeId, come posso costruire una query da Linq a Sql per trovare tutti gli antenati del dipendente? Ogni EmployeeId ha un SupervisorId associato (vedi sotto).

Ad esempio, una query degli antenati di EmployeeId 6 (Frank Black) dovrebbe restituire Jane Doe, Bob Smith, Joe Bloggs e Head Honcho.

Se necessario, posso memorizzare nella cache l'elenco di tutti i dipendenti per migliorare le prestazioni.

UPDATE:

Ho creato il seguente metodo grezzo per eseguire l'operazione. Attraversa il dipendente. Relazione del supervisore fino al nodo principale. Tuttavia, ciò genererà una chiamata al database per ciascun dipendente. Qualcuno ha un metodo più succinto o più performante? Grazie.

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;
}
È stato utile?

Soluzione

Prima di tutto, sei invitato a utilizzare le query gerarchiche nel mio progetto LINQ Extension Methods . Penso che possa aiutarti a semplificare il tuo codice.

Il problema qui è che ciò creerà una chiamata al database per ciascun nodo nella gerarchia. Nel caso del tuo esempio, avrai 5 viaggi di andata e ritorno nel database.

Vorrei seguire un percorso diverso e creare una procedura memorizzata per farlo e restituire l'intero set di oggetti Employee . Dato che stai disconnettendo gli oggetti prima di restituirli (eliminazione del contesto), potresti semplicemente creare un nuovo oggetto dal set di risultati della procedura memorizzata.

Altri suggerimenti

Una soluzione semplice che evita di caricare l'intera tabella Employee (ma ha una profondità di attraversamento limitata) è ...

var emps = dc.Employees.Where(e => (e.EmployeeId == EmployeeId) ||
                                   (e.SupervisorId == EmployeeId) ||
                                   (e.Supervisor.SupervisorId == EmployeeId) ||
                                   (e.Supervisor.Supervisor.SupervisorId == EmployeeId) ||
                                   ...);

Alla fine, dovresti usare una espressione di tabella comune per appiattire gerarchia, ma LINQ to SQL non supporta attualmente questo. Puoi cercare di scrivere il tuo metodo di estensione (come quello nella libreria di Omer ma usando IQueryable anziché IEnumerable per supportare l'esecuzione sul lato server).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top