2011-08-23 18 views
11

Considere:LINQ a las entidades + Incluir + Anónimo tema tipo

clase de cliente

Proyecto Clase

Clase de entradas

Clase Responder

Los clientes tienen una colección de sub de proyectos, los proyectos tienen una sub colección de boletos y boletos tienen una sub colección de respuestas.

var data = ctx.Set<Ticket>().Include(p => p.Client). 
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)}); 

No funciona. Ni el proyecto ni el cliente se cargan al seleccionar los datos de esta manera.

Sé cómo hacerlo funcionar. Mi pregunta es por qué no funciona así?

Respuesta

10

Como se menciona Ladislav, Include solo funciona si selecciona directamente la entidad Ticket. Como está proyectando otra información, se ignora el Include.

Esto debería proporcionar una buena solución temporal:

var data = ctx.Set<Ticket>() 
    .Select(p => new 
     { 
      Ticket = p, 
      Clients = p.Client, 
      LastReplyDate = p.Replies.Max(q => q.DateCreated) 
     }); 

En primer lugar, los clientes de cada boleto será accesible directamente desde la propiedad Clients del tipo anónimo. Además, Entity Framework debe ser lo suficientemente inteligente como para reconocer que ha extraído toda la colección Client para cada Ticket, por lo que debe funcionar llamando al .Ticket.Client.

+0

Gracias. Esa es también la solución en la que pensé. – Jeroen

+2

+1 por proporcionar una solución :) – bernhof

+0

Debo señalar a cualquiera que lea esta solución que EF no rellena mágicamente la propiedad de navegación '.Ticket.Client' con entidades devueltas con esta proyección, de modo que acceda a los clientes a través del objeto Ticket consultará la base de datos nuevamente. –

5

Porque Include funciona solo si selecciona entidades directamente. Una vez que realice la proyección, se ignora Include. No te diré por qué, pero simplemente funciona de esta manera.

+0

¿Crees que Microsoft planea cambiar eso? – billy

+0

plus1 * No le diré por qué pero simplemente funciona de esta manera. * –

2

Otra posibilidad es utilizar la solución de StriplingWarrior pero luego limpiar los datos intermedios del resultado final:

var data = ctx.Set<Ticket>() 
    .Select(p => new 
     { 
      Ticket = p, 
      Clients = p.Client, 
      LastReplyDate = p.Replies.Max(q => q.DateCreated) 
     }) 
    .AsEnumerable() 
    .Select(p => new 
     { 
      Ticket = p.Ticket, 
      LastReplyDate = p.LastReplyDate 
     }); 
Cuestiones relacionadas