2011-12-09 13 views
17

Tengo la siguiente consulta:Cómo hacer un pedido colecciones hijas de entidades en EF

public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId) 
     { 
      return _ctx.Teams 
       .Include(x => x.TeamMembers) 
       .Where(x => x.UserId == ownerUserId) 
       .OrderBy(x => x.Name).ToList(); 

     } 

¿Cómo hago para ordenar los equipos por su nombre, y luego tener todos los niños miembros de cada equipo clasificado por su ¿nombre?

Parece que para esto necesito crear una nueva clase de DTO y usar una selección. Me gustaría usar las entidades EF ya creadas, en este caso el Equipo tiene una propiedad de navegación para los Miembros. Devuelvo IEnumerable<Team> desde mi capa de repositorio.

No parece haber una manera ordenada de pedir colecciones de niños en EF. ¿Alguien puede ayudar?

+1

Aquí hay varios ejemplos: http://stackoverflow.com/a/7181574/270591, http://stackoverflow.com/a/7528266/270591, http://stackoverflow.com/a/7395406/270591 – Slauma

+0

posible duplicado de [EF 4.1 code-first: cómo ordenar las propiedades de navegación cuando se utilizan los métodos Include y/o Select?] (http://stackoverflow.com/questions/7522784/ef-4-1-code-first-how- to-order-navigation-properties-when-using-include-and-or) –

Respuesta

16

Puede cargar los datos y ordenarlos en la memoria después de cargarlos.

IEnumerable<Team> teams = _ctx.Teams 
      .Include(x => x.TeamMembers) 
      .Include(x => x.TeamMembers.Select(u => u.User)) 
      .Where(x => x.UserId == ownerUserId) 
      .OrderBy(x => x.Name).ToList(); 

foreach (var team in teams) 
{ 
    team.TeamMembers = team.TeamMembers.OrderBy(m => m.Name); 
    foreach (var teamMember in team.TeamMembers) 
    { 
     teamMember.Users = teamMember.Users.OrderBy(u => u.Name); 
    } 
} 

O podría utilizar Proyecciones y usar el Seguimiento de cambios de EF para ordenar su colección. Here is an example de filtrado de Incluir, pero lo mismo funciona para Ordenar.

+2

Gracias por esto, simple y efectivo. ¡Pensé que podría haber algo un poco más LINQish, no interesado en el bucle, pero cumple su función! – jaffa

2

Se podría volcar sus equipos y sus miembros del equipo en un tipo anónimo (probablemente no es lo que quiere), así:

public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId) 
{ 
    return (from t in _ctx.Teams 
     where t.UserId == ownerUserId 
     select new { 
      Team = t, 
      TeamMembers = t.TeamMembers.OrderBy(m => m.Name) 
     }).ToList() 
} 

A continuación, puede bucle a través de ellos:

foreach(Team team in GetAllTeamsWithMembers(1234)) 
{ 
    string teamName = team.Team.Name; 
    string firstTeamMemberName = team.TeamMembers.First().Name; 
} 

Actualización: Para el registro, mi opinión es no utilizar esta solución, sino ordenar cada colección en un bucle o durante el procesamiento/encuadernación.

Eliminé la segunda solución, ya que se indicó que EF no puede seleccionar en entidades.

+0

Desafortunadamente, la segunda opción no funciona porque LINQ to Entities no permite proyectar en una entidad. – Slauma

+0

La primera opción funciona si agrega un .Select (a => a.Team) después de su ToList(). –

+0

@Slauma No sabía eso. –

Cuestiones relacionadas