2010-08-29 17 views
8

Ho una soluzione in cui ho creato entità di auto-tracciamento utilizzando i modelli RTM. Ho diviso le entità e il contesto tra 2 progetti in modo da poter riutilizzare le definizioni dei tipi mentre pianifico di eseguire client/server tramite WCF.Entity Framework 4: caricamento Eager (Includi) con filtri che utilizzano le entità di auto-registrazione

Uno dei miei metodi di servizio è necessario per restituire un grafico di oggetti "Prodotto" con oggetti figlio di "ProductSku" e questi a loro volta hanno oggetti figlio di "ProductPrice". I criteri di selezione saranno nella proprietà "Nome" dell'oggetto "Prodotto" e nella proprietà "FinancialPeriodID" di "ProductPriceObject". Per ora, non includo il nome nella ricerca, ma sto riscontrando problemi nel riportare il grafico.

Se ho semplicemente eseguire la seguente query (nota, questa sintassi è preso da LINQPad piuttosto che il codice dell'applicazione effettiva) ...

from product in Products.Include("Skus.PriceHistory") 
select product 

... allora io sono in grado di recuperare l'oggetto grafico completo per gli articoli che richiedo, ovviamente a questo punto non ci sono filtri.

Se invece, introduco il filtro come segue ...

from product in Products.Include("Skus.PriceHistory") 
join sku in ProductSkus on product.ID equals sku.ProductID 
join price in ProductPrices on sku.ID equals price.ProductSkuID 
where price.FinancialPeriodID == 244 
select product 

... quello che mi aspetto di tornare è l'oggetti "prodotto", il bambino oggetti "productSku" (che sono in la collezione "Skus" del "Prodotto") e i loro oggetti "ProductPrice" (che sono nella collezione "PriceHistory" del "ProductSku") - ma ottengo solo gli oggetti "Prodotto", la collezione "Skus" è vuoto.

Ho anche provato la codifica la query come ...

from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select product 

... ma questo non fa alcuna differenza neanche.

Chiaramente, devo fare qualcosa di sbagliato. Qualcuno può far luce su quello che è qualcosa come sono stato a questo per alcune ore ora andando in tondo!

risposta

1

Edit:

Che dire:

from product in Products.Include("Skus.PriceHistory") 
where product.Skus.Any(s => s.PriceHistory.Any(p => p.FinancialPeriodID == 244)) 
select product 

Include svolge già tutti i compiti necessari per riempire proprietà di navigazione in modo ulteriore fughe per cui non sono necessari condizione. Ciò che è ancora più importante per qualsiasi aggiunta o proiezione manuale cambierà la forma della query e non verrà utilizzato Include.

Inoltre, fare attenzione che la condizione filtri solo i prodotti. Non filtrerà i dati caricati da Includi - otterrai tutti i prodotti con almeno uno sku con cronologia dei prezzi con l'ID 244 del periodo finanziario, ma tali prodotti avranno caricato tutti gli storici di skus e di prezzo. Attualmente EF non supporta il filtraggio su include. Se hai bisogno di relazioni filtrate, devi eseguire query separate per ottenerle.

+0

Purtroppo "SKU" e "StoricoPrezzi" sono entrambe le raccolte, quindi non è possibile navigare lungo il percorso in una singola istruzione. Temo che non ci sia altra scelta che includere i join usando il join o il come indicato nei due esempi. Grazie comunque. –

+0

Questo potrebbe non aver aiutato @MartinRobins, ma mi ha aiutato nel mio progetto! +1 Questa sintassi ha funzionato per me (forse un setup completamente diverso rispetto alla domanda originale, non lo so ...) – BenSwayne

1

Forse la proiezione può fare questo trucco?

Date un'occhiata a Linq filter collection with EF

+0

Grazie, ma voglio davvero ridurre al minimo il numero di tipi di oggetti che sto passando in giro. Ho già un ottimo tipo di "Prodotto", voglio solo che il caricamento ansioso funzioni correttamente così che gli oggetti figlio siano popolati. –

-1

entità auto-monitoraggio non sono abilitati ad effettuare il caricamento pigro. Ecco perché la raccolta non è vuota con la generazione di entità predefinita e non con STE. In effetti il ​​tuo include non carica mai le entità correlate se le usi sulla query. Ora la tua query L2E non è corretta.Penso che si vuole fare qualcosa di simile:

Speranza che aiuta

Matthieu

+0

Non sto tentando di utilizzare il caricamento lazy; Sto provando ad usare il caricamento avido. Se rimuovo la clausola where, o la baso solo sull'oggetto di livello superiore, ottengo tutti gli oggetti correttamente. È solo quando utilizzo la clausola where in base alle proprietà degli oggetti figlio che il "Include" viene ignorato. –

+0

Ciao Martin, hai trovato una soluzione, ho lo stesso problema – freddoo

0

Avere includere non è una garanzia di avere eager loading e poteva essere ignorato in silenzio per i seguenti motivi ragionare. È meglio spiegato in questo thread. Puoi selezionare manualmente la tabella che desideri caricare, ad es.

var result = from product in Products.Include("Skus.PriceHistory") 
from sku in product.Skus 
from price in sku.PriceHistory 
where price.FinancialPeriodID == 244 
select new { p=product, pricehistory = product.Skus.PriceHistory}; 
var products = results.select(pph => pph.product); 

https://social.msdn.microsoft.com/Forums/en-US/76bf1f22-7674-4e1e-85d3-68d29404e8db/include-is-ignored-in-a-subquery?forum=adodotnetentityframework

  • Include applica solo agli elementi nei risultati dell'interrogazione: oggetti che sono proiettata al funzionamento più esterna nella query.
  • Il tipo di risultati deve essere un tipo di entità.
  • La query non può contenere operazioni che modificano il tipo del risultato tra include e l'operazione più esterno (cioè un GroupBy() o Select() operazione che cambia il tipo di risultato)
  • Il parametro presa da inserire sono un percorso delimitata da punti di navigazione proprietà che devono essere navigabile da un'istanza del tipo restituita al funzionamento più esterno
Problemi correlati