Je travaille sur l'ajout d'un HtmlHelper pour la pagination, mais je ne suis pas sûr de l'endroit approprié et/ou le plus bénéfique pour mettre certaines parties du code de pagination du point de vue de la performance et de la maintenabilité. Je ne suis pas certain que les parties Skip(), Take() et Count() de la manipulation de données Linq to SQL doivent rester dans le référentiel ou dans le contrôleur.ASP.NET MVC2 LINQ - Modèle de référentiel, où doit aller le code de pagination?
Je ne sais pas non plus si leur commande et l'endroit où ils sont utilisés affectent les performances de quelque façon que ce soit.
S'ils vivent dans le dépôt de ma compréhension Voici comment cela fonctionnerait:
1. je passerais le pageIndex et pageSize comme arguments à la méthode du dépôt qui saisit les données de la base de données.
2. Ensuite, récupérez l'ensemble de données complet de la base de données.
3. Ensuite, stockez le nombre de TotalItems de cet ensemble de données complet dans une variable.
4. Ensuite, appliquez Skip() et Take() pour que l'ensemble de données ne conserve que la page dont j'ai besoin.
5. Afficher l'ensemble de données partiel sous la forme d'une seule page dans la vue. Si elles vivent dans le contrôleur à ma compréhension, voici comment cela fonctionnerait: 1. Je voudrais récupérer l'ensemble complet du dépôt et le stocker dans une variable à l'intérieur du contrôleur. 2. Ensuite, obtenez le nombre de TotalItems pour l'ensemble de données complet. 3. Ensuite, appliquez Skip() et Take() pour que l'ensemble de données ne conserve que la page dont j'ai besoin. 4. Affichez l'ensemble de données partiel sous la forme d'une seule page dans la vue.
A l'intérieur du contrôleur (je me rends compte que je vais mal obtenir la page compte ici et non TotalItems):
Character[] charactersToShow = charactersRepository.GetCharactersByRank(this.PageIndex, this.PageSize);
RankViewModel viewModel = new RankViewModel
{
Characters = charactersToShow,
PaginationInfo = new PaginationInfo
{
CurrentPage = this.PageIndex,
ItemsPerPage = this.PageSize,
TotalItems = charactersToShow.Count()
}
};
A l'intérieur du dépôt:
public Character[] GetCharactersByRank(int PageIndex, int PageSize)
{
IQueryable characters = (from c in db.Characters
orderby c.Kill descending
select new Character {
CharID = c.CharID,
CharName = c.CharName,
Level = c.Level
});
characters = PageIndex > 1 ? characters.Skip((PageIndex - 1) * PageSize).Take(PageSize) : characters.Take(PageSize);
return characters.ToArray();
}
Ce code est un exemple partiel de la façon dont je implémentait le code Skip(), Take() et Count() vivant dans le référentiel. Je n'ai pas réellement implémenté l'obtention et le renvoi des TotalItems parce que je me suis rendu compte que je ne connaissais pas l'endroit approprié pour mettre cela.
Une partie de la raison pour laquelle je ne sais pas où les mettre est que je ne sais pas comment Linq to SQL fonctionne sous le capot, et donc je ne sais pas comment optimiser les performances. Je ne sais pas si c'est même un problème dans cette affaire.
Est-ce qu'il doit saisir tous les enregistrements de la base de données lorsque vous faites un .Count() sur Linq to SQL? Est-ce qu'il doit faire des requêtes séparées si je fais un .Count(), puis plus tard faire un .Skip() et .Take()? Y at-il des problèmes de performances possibles avec l'utilisation de .Count() avant un .Skip() et .Take()?
C'est la première fois que j'utilise un ORM, donc je ne sais pas à quoi m'attendre. Je sais que je peux voir les requêtes Linq à SQL est en cours d'exécution, mais je pense qu'écouter quelqu'un avec de l'expérience dans ce cas serait une meilleure utilisation de mon temps.
Je voudrais comprendre cela plus en profondeur, toute idée serait appréciée.
pour répondre * une * de vos questions, oui - Il faut faire 2 appels DB. Le seul moyen d'éviter cela est de faire le paging 100% dans la base de données elle-même. – RPM1984