2011-11-07 3 views
1

Je reçois l'erreur:Asp.net MVC erreur: LINQ to Entities ne reconnaît pas

LINQ to Entities ne reconnaît pas la méthode « PagedList.IPagedList 1[MvcMusicStore.Models.Album] ToPagedList[Album](System.Collections.Generic.IEnumerable 1 [MvcMusicStore.Models.Album], Int32, Int32) » méthode, et cette méthode ne peut pas être traduit en une expression de magasin

pour mon action de commande suivante:

public ActionResult Browse(string genre, int?page) 
    { 
     // Retrieve Genre and its Associated Albums from database 
     int pageIndex = page ?? 1; 
     var genreModel = storeDB.Genres.Where(g => g.Name == genre) 
             .Select(g => new GenreAlbumView 
             { 
              ID = g.GenreId, 
              Name = g.Name, 
              Albums = g.Albums.ToPagedList(pageIndex, PageSize) 
             }).SingleOrDefault(); 
     return View(genreModel); 
    } 

Quelle peut être la raison et la solution à ce problème?

Répondre

2

d'abord exécuter votre requête genermodel:

var genreModel = storeDB.Genres.Where(g => g.Name == genre).SingleOrDefault(); 

Lancez ensuite votre sélection.

Parce que le soutien de la fonctionnalité est limitée lin2entity et ne peut pas convertir votre fonction:

g.Albums.ToPagedList(pageIndex, PageSize) 

à commande SQL approprié, en fait, il ne peut pas créer l'arbre d'expression connexes pour elle, donc vous devez d'abord obtenir des entités et puis sélectionnez comme vous le souhaitez.

Si vous devez effectuer une telle pagination dans DB, créez une procédure stockée et utilisez-la.

+0

Merci mon frère mais je ne sais pas quelle réponse marquer comme acceptée :-). Les deux réponses fonctionnent et je ne sais pas qui fonctionne le mieux. –

+0

@Pankaj espère que cela vous a aidé si les deux réponses ont la même valeur pour vous retourner la pièce :) –

+0

LOL ... J'ai marqué cela comme réponse car il semble une meilleure approche. Et aussi, je ne trouve aucune raison ou situation quand on devrait utiliser préfèrent sauter et prendre en charge cette approche. –

1

Le problème est que la méthode ToPagedList n'est pas quelque chose qui peut être traduit en requête SQL et exécuté dans la base de données.

Pour la recherche sur le serveur de base de données, vous pouvez utiliser les méthodes Passer et prendre.

Effectuez les actions suivantes:

var genreModel = storeDB.Genres.Where(g => g.Name == genre) 
             .Select(g => new GenreAlbumView 
             { 
              ID = g.GenreId, 
              Name = g.Name, 
              Albums = g.Albums.Skip(PageSize * (PageIndex -1)).Take(PageSize) 
             }).SingleOrDefault(); 

Lorsque vous utilisez Saut/Take qui peut être traduit en une commande SQL, la pagination sera effectuée sur le serveur de base de données, mais lorsque vous exécutez la requête, puis appelez la Méthode ToPagedList vous aurez un coup de performance. La pagination est ensuite exécutée en mémoire sur tous les albums déjà chargés à partir de la base de données.

Ce principe a trait à ce que Linq appelle l'exécution différée. Vous construisez un arbre d'expression qui est traduit uniquement en SQL lorsque vous exécutez l'arbre d'expression (avec par exemple Single, ToList, First, Count ou des méthodes similaires) la commande Sql est générée et exécutée sur le serveur de base de données. Par conséquent, si vous appelez 'ToList' et que vous appelez la pagination, vous récupérerez tous les enregistrements de la base de données et les enregistrerez en mémoire, ce qui sera beaucoup plus lent.

+0

Merci mon ami d'avoir touché la question plus profonde et de m'avoir fait comprendre pourquoi cela se passait. –

+0

Désolé compagnon j'ai marqué la réponse de Saeed comme accepté car il semblait codage propre et une meilleure approche. Mais, pouvez-vous m'aider à comprendre toute situation lorsque l'on préfère ou que l'on a besoin d'utiliser skip/take over l'approche de Saeed. –

Questions connexes