2010-08-29 16 views
8

J'ai une solution où j'ai créé des entités de suivi automatique en utilisant les modèles RTM. J'ai divisé les entités et le contexte entre 2 projets afin que je puisse réutiliser les définitions de type que j'ai l'intention d'exécuter le client/serveur par l'intermédiaire de WCF.Entity Framework 4: Eager Chargement (Inclure) avec des filtres utilisant des entités de suivi automatique

Une de mes méthodes de service est requise pour renvoyer un graphique des objets "Product" avec des objets enfants de "ProductSku" et ceux-ci ont à leur tour des objets enfants de "ProductPrice". Les critères de sélection seront sur la propriété "Name" de l'objet "Product" et la propriété "FinancialPeriodID" de "ProductPriceObject". Pour l'instant, je n'inclus pas le nom dans la recherche, mais j'ai des problèmes pour ramener le graphique.

Si j'effectuez simplement la requête suivante (note, cette syntaxe est tirée de LINQPad plutôt que le code d'application réelle) ...

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

... je suis en mesure de récupérer le plein graphe d'objet pour les articles dont j'ai besoin, bien sûr, à ce stade, il n'y a pas de filtre.

Si, au contraire, je vous présente le filtre comme suit ...

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 

... ce que j'attends de retourner les objets est « produit », l'enfant des objets « productSKU » (qui sont en la collection "Skus" du "Produit") et leurs objets "ProductPrice" (qui sont dans la collection "PriceHistory" du "ProductSku") - mais je récupère seulement les objets "Product", la collection "Skus" est vide.

J'ai aussi essayé coder la requête comme ...

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

... mais cela fait soit pas de différence.

De toute évidence, je dois faire quelque chose de mal. Quelqu'un peut-il nous éclairer sur ce que c'est que ce que je fais depuis quelques heures maintenant en rond!

Répondre

1

Edit:

Qu'en est-:

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

Include exécute déjà toutes les tâches nécessaires pour remplir les propriétés de navigation se joint donc au plus pour savoir où la condition ne sont pas nécessaires. Ce qui est encore plus important, toute jointure ou projection manuelle va changer la forme de la requête et Include ne sera pas utilisé.

Méfiez-vous également que lorsque la condition filtre uniquement les produits. Il ne filtrera pas les données chargées par Inclure - vous obtiendrez tous les produits avec au moins un sku ayant un historique de prix avec l'identifiant de période financière 244 mais ces produits auront tous les skus et historiques de prix chargés. EF ne prend actuellement pas en charge le filtrage sur include. Si vous avez également besoin de relations filtrées, vous devez exécuter des requêtes distinctes pour les obtenir.

+0

Désolé, « SKUS » et « PriceHistory » sont les deux collections, il est donc impossible de naviguer tout le long du chemin dans une seule déclaration. Je crains qu'il n'y ait pas d'autre option que d'inclure les jointures en utilisant soit la jointure, soit le from comme indiqué dans les deux exemples. Merci quand même. –

+0

Cela n'a peut-être pas aidé @MartinRobins, mais cela m'a aidé dans mon propre projet! +1 Cette syntaxe a fonctionné pour moi (installation peut-être totalement différente de la question originale, je ne sais pas ...) – BenSwayne

1

Peut-être que la projection peut faire cette astuce?

Jetez un oeil à Linq filter collection with EF

+0

Merci, mais je veux vraiment minimiser le nombre de types d'objets que je suis en train de contourner. J'ai déjà un très bon type "Product", je veux juste que le chargement impatient fonctionne correctement pour que les objets enfants soient peuplés. –

-1

entités autovirants ne sont pas activés pour effectuer le chargement paresseux. C'est pourquoi la collecte n'est pas vide avec la génération d'entité par défaut et pas avec STE. En fait, votre Include ne charge jamais les entités associées si vous les utilisez dans la requête. Maintenant, votre requête L2E n'est pas correcte.Je pense que vous voulez faire quelque chose comme ceci:

espoir qui aide

Matthieu

+0

Je n'essaie pas d'utiliser le chargement paresseux; J'essaie d'utiliser le chargement impatient. Si je supprime la clause where ou si je la base uniquement sur l'objet de niveau supérieur, tous les objets sont correctement récupérés. Ce n'est que lorsque j'utilise la clause where basée sur les propriétés des objets enfants que le paramètre "Include" est ignoré. –

+0

Salut Martin, as-tu trouvé une solution, j'ai le même problème – freddoo

0

Avoir Inclure est pas une garantie d'avoir le chargement désireux et il pourrait être ignoré en silence à cause des éléments suivants raison. Il est mieux expliqué dans ce fil. Vous pouvez sélectionner manuellement la table que vous souhaitez charger, par ex.

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

  • Inclure ne vise que les articles dans les résultats de la requête: les objets qui sont projetée lors de l'opération la plus externe dans la requête.
  • Le type des résultats doit être un type d'entité.
  • La requête ne peut pas contenir des opérations qui changent le type du résultat entre Inclure et l'opération la plus externe (par exemple un GroupBy() ou une opération de sélection() qui modifie le type de résultat)
  • Le paramètre pris par Inclure est un chemin de points délimités par des propriétés de navigation qui doivent être navigable à partir d'une instance du type retourné à l'opération la plus externe
Questions connexes