2009-11-08 12 views
5

Tenemos clasesLINQ a las entidades - buscando en las propiedades de navegación EntityCollection

public Invoice: EntityObject 
{ 
    public EntityCollection<InvoicePosition> Positions { get {...}; set{...}; } 
    ... 
} 

public InvoicePosition: EntityObject 
{ 
    public string GroupName { get {...}; set{...}; } 
} 

se nos da IQueryable<Invoice>, no se dan IQueryable<InvoicePosition>. ¿Cómo debo encontrar las facturas que tienen posiciones, donde GroupName es 'Combustible'?

IQueryable<Invoice> invoices = InvoiceRepository.List(); 
IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices 
    where ? 
    select i 

ADO.NET Entity Framework debe ser capaz de traducirlo a consulta SQL adecuado.

EDITAR

Como escribió Marcos Seemann, puedo usar:

IQueryable<Invoice> invoices = InvoiceRepository.List().Include("Positions").Include("OtherInclude"); 
IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices 
    from p in i.Positions 
    where p.GroupName = 'Fuel' 
    select i; 

Hay un problema. Cuando uso este filtro, pierdo "OtherInclude". Creo que esta no es la forma correcta de filtrar cuando se usa EF. Tendré que cambiarlo a:

IQueryable<Invoice> invoices = InvoiceRepository.List().Include("Positions").Include("OtherInclude"); 
IQueryable<Invoice> invoicesThatHaveFuelPositions = invoices.Where(???); 

Pero, ¿qué debería escribir en Dónde?

EDITAR

cambiado include ("Posición") para incluir ("posiciones").

EDITAR

Alex James dio un enlace a la punta (http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx), lo que sugiere:

IQueryable<Invoice> invoicesThatHaveFuelPositions = 
    from i in invoices 
    where i.Positions.Any(p => p.GroupName == 'Fuel') 
    select i; 

Parece que funciona y no influye en EF incluye.

Respuesta

5

Basándose en respuesta Marcas. Si hace esto:

var q = from i in invoices.Include("something") 
     from p in i.Positions 
     where p.GroupName == "Fuel" 
     select i; 

El incluyen se pierde (ver this tip) debido a que el EF pierde toda incluye si la forma de los cambios de consulta, por ejemplo, si lo hace implícita se une al igual que en una consulta SelectMany, alias de partir .

La solución consiste en escribir su consulta y, al final, aplicar Incluir.

Algo como esto:

var q = ((from i in invoices 
     from p in i.Positions 
     where p.GroupName == "Fuel" 
     select i) as ObjectQuery<Invoice>).Include("something"); 

Si hace esto Entity Framework en realidad no la incluyen.

Esperanza esto ayuda

Alex

+0

Gracias por este consejo. Agregar inclusión al final es problemático, porque utilizo el patrón de repositorio y las inclusiones se aplican primero. La solución del medio (usando Any()) me queda bien. – LukLed

2

Algo como esto se debe trabajar;

var q = from i in invoices 
     from p in i.Positions 
     where p.GroupName == "Fuel" 
     select i; 

Sin embargo, que utiliza la propiedad de navegación Positions, que por defecto no está cargado (Entity Framework utiliza la carga explícita). Será, sin embargo, el trabajo, si la variable invoices fue creado de esta manera:

var invoices = from i in myObjectContext.Invoices.Include("Positions") 
       select i; 
+0

Si se compila, tal vez sería trabajar :) – LukLed

+0

Invoice.Positions es EntityCollection. No tiene propiedad GroupName. Tiene una lista de InvoicePosition. – LukLed

+0

Lo siento, leí mal el código en la pregunta. Acabo de actualizar la respuesta. –

Cuestiones relacionadas