Pregunta

Dado un Id. de empleado, ¿cómo puedo construir una consulta de Linq a Sql para encontrar a todos los antepasados ??del empleado? Cada Id. De empleado tiene un SupervisorId asociado (ver más abajo).

Por ejemplo, una consulta de los antepasados ??para EmployeeId 6 (Frank Black) debería devolver a Jane Doe, Bob Smith, Joe Bloggs y Head Honcho.

Si es necesario, puedo almacenar en caché la lista de todos los empleados para mejorar el rendimiento.

UPDATE:

He creado el siguiente método crudo para realizar la tarea. Atraviesa al empleado. La relación del supervisor hasta el nodo raíz. Sin embargo, esto emitirá una llamada a la base de datos para cada empleado. ¿Alguien tiene un método más sucinto o más eficaz? Gracias.

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;
}
¿Fue útil?

Solución

En primer lugar, puede utilizar las consultas jerárquicas en mi proyecto LINQ Extension Methods . Creo que puede ayudar a simplificar su código.

El problema aquí es que esto creará una llamada a la base de datos para cada nodo en la jerarquía. En el caso de su ejemplo, tendrá 5 viajes de ida y vuelta a la base de datos.

Iría por un camino diferente y crearía un procedimiento almacenado para hacer eso por mí y devolvería el conjunto completo de objetos Employee . Como está desconectando los objetos antes de devolverlos (eliminando el contexto), simplemente puede crear un nuevo objeto a partir del conjunto de resultados del procedimiento almacenado.

Otros consejos

Una solución simple que evita cargar toda la tabla de empleados (pero tiene una profundidad transversal limitada) es ...

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

En última instancia, debe utilizar una expresión de tabla común para aplanar la jerarquía, pero LINQ to SQL actualmente no es compatible con esto. Puede buscar escribir su propio método de extensión (como el de la biblioteca de Omer pero usando IQueryable en lugar de IEnumerable para admitir la ejecución del lado del servidor).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top