2011-04-08 5 views
4

J'ai une requête compilée qui fonctionne très bien. Je lui passe un product_id et il renvoie les informations de révision de produit pour ce produit.Puis-je utiliser une requête compilée en tant que source dans une deuxième requête?

Est-il possible d'utiliser cette requête compilée comme source pour une sous-requête? Exemple:

from cat in ctx.cat_table 
join prod in ctx.prod_table on cat.category_id equals prod.category_id 
select new 
{ 
    cat_id = cat.category_id, 
    prod_id = prod.product_id, 
    name = prod.product_name, 
    descript = prod.product_description, 
    price = prod.price, 
    reviews = (from mcq in mycompiledquery(ctx, prod.product_id) 
       select new 
       { 
        rating = mcq.review_rating, 
        review = mcq.review_text 
       }  
} 

Mes premières tentatives de faire quelque chose comme ceci soulève une erreur:

The LINQ expression node type 'Invoke' is not supported in LINQ to Entities

Une alternative que j'ai pensé est de remplacer ma requête compilé avec une vue SQL, mais je suis préoccupé par un impact négatif sur les performances.

Un grand merci pour toutes les suggestions que vous pouvez offrir.

Répondre

2

Vous pouvez utiliser la requête compilée dans d'autres requêtes, mais vous ne pouvez pas le faire en fonction de la requête externe. Exemples

// You can do 
var someParams = 10; 
var dataQuery = from x in ctx.SomeData 
       join y in myCompiledQuery.Invoke(ctx, someParams) 
        on x.Id equals y.Id 
       where x.Name = "ABC" 
       select new { x, y }; 

// You can't do - this example will not compile but let's use it for description 
var dataQuery = from x in ctx.SomeData 
       join y in myCompiledQuery.Invoke(ctx, x.SomeParams) 
        on x.Id equals y.Id 
       where x.Name = "ABC" 
       select new { x, y }; 

La différence est que le premier exemple qu'exécuter délégué (requête compilé est un délégué) et retourne IQueryable. Le deuxième exemple ne peut pas exécuter de délégué car il dépend des données de requête externes, donc il le prend comme quelque chose qui doit être ajouté à l'arbre d'expression et éveillé lors de l'exécution de la requête. Cela échoue car le fournisseur EF n'est pas en mesure de traduire l'appel de délégué.

+0

Merci, c'est logique. J'apprécie la comparaison directe. – karman

0

Vous pouvez combiner et intégrer des requêtes, mais je ne pense pas que vous puissiez utiliser des requêtes compilées. Cela ne devrait cependant pas avoir beaucoup d'importance car EF ne compilera qu'une seule fois la requête combinée puis la mettra en cache (et le backend de la base de données devrait mettre en cache le plan de requête associé).

Vous pouvez donc utiliser quelque chose le long de ces lignes:

var reviewQuery = from mcq in reviews 
        select new 
        { 
         prod_id = mcq.prod_id 
         rating = mcq.review_rating, 
         review = mcq.review_text 
        }; 

from cat in ctx.cat_table 
join prod in ctx.prod_table on cat.category_id equals prod.category_id 
select new 
{ 
     cat_id = cat.category_id, 
     prod_id = prod.product_id, 
     name = prod.product_name, 
     descript = prod.product_description, 
     price = prod.price, 
     reviews = from r in reviewQuery where r.prod_id == prod_id select r 
} 
+0

Merci Morten. C'est peut-être ma meilleure option. – karman

Questions connexes