2010-12-15 12 views
6

Tengo una colección de empleados, y cada empleado tiene una colección de responsabilidades. Me gustaría generar una lista de los empleados ordenados por nombre y dar salida a sus responsabilidades, ordenadas por título.¿Cómo pedir una colección y su subcolección usando LINQ?

Por lo tanto, hay que emitir la siguiente manera:


Jane Jones

Responsabilidades:

Responsabilidad Un

Responsabilidad B

Mike Smith

Responsabilidades:

Responsabilidad Un

Responsabilidad C


Para obtener la colección inicial que utilizo:

var employees = _context.Employees.OrderBy(e => e.Name); 

pero me parece que no puede encontrar la manera de ordenar la subcolección de Responsabilidades también.

Estoy utilizando MVC y mi vista recibe una colección de empleados fuertemente tipificados, por lo que no quiero compilar y devolver un tipo anónimo.

+0

He decidido no ordenar la colelction cuando me tire de ella a partir de la base de datos. Técnicamente, ordenar es parte de la presentación, así que ahora lo estoy haciendo en View (estoy usando MVC). Ahora estoy ordenando la subcolección cuando hago un foreach sobre el empleado. Responsabilidades. –

+0

Sin embargo, sería bueno saber cómo hacer esto para referencia futura. ¡Gracias! –

+0

He agregado el segundo enfoque ... Lo siento, es bastante pesado también. No creo que haya una manera más fácil, así que estoy de acuerdo con usted: sería mucho mejor hacer un pedido en la vista o crear algún DTO especial (Data Transfer Object) y hacer una proyección en él y luego pasar a la vista en lugar del empleado –

Respuesta

2

primera aproximación: (es sólo apto para LINQ a objetos con responsabilidades definidas como IList)

Se puede copiar en una nueva colección de empleados, pero esto significa que usted necesita para volver a copiar cada campo en un nuevo empleado, algo como esto:

var employees = from e in _context.Employees 
       orderby e.Name 
       select new Employee 
       { 
        Name = e.Name, 
        ...re-assign other properties... 
        Responsibilities = e.Responsibilities.OrderBy(r => r.Name).ToList() 
       }; 

segundo enfoque:

Usando el DataLoadOptions. Básicamente, se crea un objeto DataLoadOptions que especifica cómo ordenar una relación particular, por lo que en su caso:

var options = new DataLoadOptions(); 
options.AssociateWith<Employees>(e => e.Responsibilities.OrderBy(r => r.Name)); 
_context.LoadOptions = options; 

var employees = _context.Employees.OrderBy(e => e.Name); 

Las responsabilidades serán ordenados de forma automática.

+0

Yo también creo que es un desperdicio volver a copiar cada campo. En realidad, cuando intento esto me sale un error que no puedo convertir un objeto de IQueryable a EntityCollection. Entonces esto no funciona para mí. –

+0

Sí, necesita ser convertido a EntitySet vs List ... además no puede crear un nuevo empleado dentro de la consulta b/c L2S no lo permite, por lo que parece que solo se puede usar la segunda opción en su escenario. –

3

Se podría hacer algo como:

var employees = _context.Employees.OrderBy(e => e.Name); 
employees.ToList().ForEach(e => e.Responsibilities = e.Responsibilities.OrderBy(r => r.Name)); 
+0

Cuando intento esto obtengo el error: No puedo convertir el tipo de fuente IOrderedEnumerable <> al tipo de destino EntityCollection <>. –

+0

Funcionó para mí. No estoy seguro de que sea la mejor manera para mi caso particular, pero por ahora me quedaré con eso. – Jeroen

+0

Para alguien que recibe el error 'No se puede convertir el tipo de fuente IOrderedEnumerable <> al tipo de destino EntityCollection <>'. Usted acaba de convertirlo a la lista a saber. 'employees.ToList(). ForEach (e => e.Responsibilities = e.Responsibilities.OrderBy (r => r.Name) .ToList());' –

Cuestiones relacionadas