Ich arbeite daran, einen HtmlHelper für die Paginierung hinzuzufügen, bin mir aber unsicher, wo der richtige und/oder vorteilhafteste Ort ist, um bestimmte Teile des Paginierungs codes aus Leistungs- und Wartbarkeitssicht zu platzieren.
Ich bin mir unsicher, ob die Teile Skip(), Take() und Count() der Datenmanipulation von Linq to SQL im Repository oder im Controller platziert werden sollten.
Ich bin mir auch unsicher, ob ihre Reihenfolge und wo sie verwendet werden, die Leistung in irgendeiner Weise beeinflusst.
Wenn sie sich im Repository befinden, würde dies meiner Meinung nach so funktionieren:
1. Ich würde die pageIndex und pageSize als Argumente an die Methode des Repository übergeben, die die Daten aus der Datenbank abruft.
2. Dann die vollständige Datensatz aus der Datenbank abrufen.
3. Dann die Anzahl von TotalItems dieses vollständigen Datensatzes in einer Variable speichern.
4. Dann Skip() und Take() anwenden, damit der Datensatz nur die Seite behält, die ich brauche.
5. Den Teil-Datensatz in der Ansicht als einzelne Seite anzeigen.
Wenn sie sich im Controller befinden, würde dies meiner Meinung nach so funktionieren: 1. Ich würde den vollständigen Datensatz aus dem Repository abrufen und in einer Variablen im Controller speichern. 2. Dann die Anzahl von TotalItems für den vollständigen Datensatz abrufen. 3. Dann Skip() und Take() anwenden, damit der Datensatz nur die Seite behält, die ich brauche. 4. Den Teil-Datensatz in der Ansicht als einzelne Seite anzeigen.
Im Controller (mir ist bewusst, dass ich hier die Seitenzahl falsch erhalte und nicht 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()
}
};
Im Repository:
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();
}
Dieser Code ist ein teilweises Beispiel dafür, wie ich die Skip(), Take() und Count() code im Repository implementiert habe. Ich habe TotalItems nicht tatsächlich abgerufen und zurückgegeben, weil mir dann klar wurde, dass ich nicht wusste, wo ich das richtig platzieren sollte.
Ein Teil des Grundes, warum ich unsicher bin, wo ich diese platzieren soll, ist, dass ich nicht weiß, wie Linq to SQL unter der Oberfläche funktioniert, und daher nicht weiß, wie ich für die Leistung optimieren kann. Noch weiß ich, ob dies in diesem Fall überhaupt ein Problem ist.
Muss es alle Datensätze aus der Datenbank abrufen, wenn man ein .Count() auf dem Linq to SQL durchführt? Muss es separate Abfragen machen, wenn ich ein .Count() mache und später ein .Skip() und .Take() mache? Gibt es mögliche Leistungsprobleme bei der Verwendung von .Count() vor einem .Skip() und .Take()?
Das ist mein erstes Mal, dass ich ein ORM verwende, also weiß ich nicht, was ich erwarten soll. Ich weiß, dass ich die Abfragen, die Linq to SQL ausführt, sehen kann, aber ich denke, dass es besser wäre, jemanden mit Erfahrung in diesem Fall zu hören.
Ich möchte dies genauer verstehen, jeder Einblick wäre geschätzt.