2010-04-08 5 views
1

Dans mon application, je retire le "flux" d'un utilisateur. Celui-ci contient toutes les activités de cet utilisateur, les événements, les demandes d'amis d'autres utilisateurs, etc. Lorsque je retire le flux, j'appelle diverses fonctions pour filtrer la requête en cours de route.LINQ à entités retirant toute la table

 var userFeed = GetFeed(db); // Query to pull back all data 
     userFeed = FilterByUser(userFeed, user, db); // Filter for the user 
     userFeed = SortFeed(userFeed, page, sortBy, typeName); // Sort it 

Les données qui est retourné est exactement ce que je dois, cependant, quand je regarde un profil SQL Trace je peux voir que la requête qui obtient ces données ne filtre pas au niveau de la base de données et au lieu est la sélection TOUTES les données dans le (s) tableau (s).

Cette requête ne s'exécute pas jusqu'à ce que je parcourir les résultats sur ma vue. Toutes ces fonctions renvoient un objet IEnumerable. J'ai eu l'impression que LINQ prendrait tous mes filtres et formerait une requête pour récupérer les données que je veux au lieu de retirer toutes les données et de les filtrer ensuite sur le serveur. Qu'est-ce que je fais de mal ou qu'est-ce que je ne comprends pas à propos de la manière dont LINQ évalue les requêtes?

Répondre

4

Si GetFeed renvoie un IEnumerable, FilterByUser recevra un IEnumerable. Quand il appelle un opérateur LINQ, c'est-à-dire Où, il utilisera l'IEnumerable Where, qui commencera à demander des informations, qui finira par télécharger la totalité de la table. Changez le type de GetFeed en IQueryable pour vous assurer que les opérateurs LINQ de IQueryable sont appelés à la place, ce qui retardera la requête.

+0

Lors de la modification du type de retour de mes fonctions, j'obtiens: L'entité ou le type complexe 'Feed' ne peut pas être construit dans une requête LINQ to Entities. Si ma compréhension de cette erreur est correcte, cela signifie que tous mes filtres ne peuvent pas être transformés en une requête. Si c'est vrai, quelle est la meilleure façon d'aborder cela? – XVargas

+0

Vous devrez sélectionner les informations dont vous avez besoin pour construire le type de données dans une classe anonyme, puis effectuer AsEnumerable() et Select de l'objet de classe anonyme au type de données: x.Select (something => new {something. data, something.moreData}). AsEnumerable(). Sélectionnez (wrapped => new Feed (wrapped.data, wrapped.moreData) LINQ to SQL est capable de le faire automatiquement même à l'intérieur des requêtes (il fait quelque chose comme ça automatiquement), donc je ne suis pas sûr si je manque quelque chose – Jesper

+0

Voici le code en question Je crois que la méthode GedFeed fait juste ce que vous dites, c'est dans son état d'origine avant que j'essaye de régler les types de retour à IQueryable http://pastebin.com/R38mWGXH ​​ – XVargas