2009-11-08 13 views
5

Abbiamo classiLINQ to entità - la ricerca in EntityCollection proprietà di navigazione

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

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

c'è dato IQueryable<Invoice>, che non sono dati IQueryable<InvoicePosition>. Come dovrei trovare fatture con posizioni, dove GroupName è 'Carburante'?

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

EntityFramework deve essere in grado di tradurlo in una query sql corretta.

EDIT

Come ha scritto Mark Seemann, posso usare:

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; 

c'è un problema. Quando utilizzo questo filtro, perdo "OtherInclude". Penso che questo non sia il modo corretto di filtrare quando si usa EF. Dovrò cambiarlo in:

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

Ma cosa dovrei scrivere in Dove?

EDIT

cambiamento sono compresi ("Posizione") da includere ("Posizioni").

EDIT

Alex James ha dato link per la punta (http://blogs.msdn.com/alexj/archive/2009/06/02/tip-22-how-to-make-include-really-include.aspx), che suggerisce:

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

Sembra funzionare e non influenza EF comprende.

risposta

5

Sulla Marks risposta. Se si esegue questa operazione:

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

Il includono si perde (vedi this tip) perché l'EF perde tutto comprende se la forma dei cambiamenti di query, ad esempio, se si fa implicitamente si unisce come in una query SelectMany, aka da da .

La soluzione alternativa è scrivere la query, quindi alla fine applicare l'opzione Includi.

Qualcosa di simile a questo:

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

Se si esegue questa operazione Entity Framework in realtà non la comprende.

Spero che questo aiuti

Alex

+0

Grazie per questo suggerimento. Aggiungere Includi alla fine è problematico, perché utilizzo il pattern di repository e Include sono applicati per primi. La soluzione centrale (usando Any()) mi sta bene. – LukLed

2

Qualcosa del genere dovrebbe funzionare:

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

tuttavia, che utilizza la proprietà di navigazione Positions, che di default non è caricato (Entity Framework utilizza caricamenti espliciti). Sarà, tuttavia, il lavoro, se la variabile invoices è stato creato in questo modo:

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

Se compilato, forse avrebbe funzionato :) – LukLed

+0

Invoice.Positions è EntityCollection. Non ha la proprietà GroupName. Ha un elenco di InvoicePosition. – LukLed

+0

Spiacente, ho letto male il codice nella domanda. Ho appena aggiornato la risposta. –

Problemi correlati