This article has been localized into Dutch by the community.
Beperken data: de Take() & Skip() methods
Tot nu toe hebben we in dit LINQ hoofdstuk van het tutorial verschillende manieren ontdekt om via LINQ met databronnen te werken. Nu is de tijd daar om te zien of we de hoeveelheid data om mee te werken kunnen beperken. Dit is vooral nuttig wanneer je een database als bron gebruikt, omdat die vaak enorme hoeveelheden rijen omvat, die echte capaciteit vreters zijn om op te halen.
De methoden die we in dit artikel bespreken heten Take() en Skip(), en in combinatie doen ze het erg goed bij zoiets als het pagineren bij een website. In feite worden ze vaak samen gebruikt, maar ze kunnen natuurlijk ook apart gebruikt worden. De Take() method brengt je een X aantal items uit de databron, terwijl Skip() toestaat dat je de eerste X items negeert. Een simpel voorbeeld zou er zo uit kunnen zien:
List<string> names = new List<string>()
{
"John Doe",
"Jane Doe",
"Joe Doe",
"Jenna Doe",
};
var middleNames = names.Skip(1).Take(2).ToList();
foreach (var name in middleNames)
Console.WriteLine(name);
We creƫren een eenvoudige lijst van namen en daarna, voor de output, slaan we de eerste naam (Skip(1)) over, en nemen vervolgens de volgende twee namen (Take(2)), waardoor we slechts de middelste twee namen uit de lijst overhouden.
Basale paginering met Skip()en Take()
Zoals je ziet zijn de beide Take() en Skip() methods heel eenvoudig te gebruiken, maar het wordt interessanter bij gebruik van meer data dan voorheen. Dus nam ik de vrijheid om een iets complexer voorbeeld te bedenken, wat beter laat zien hoe deze methods je kunnen helpen. Eerst dan maar de code:
using System;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
namespace LinqTakeSkip1
{
class Program
{
static void Main(string[] args)
{
CultureInfo usCulture = new CultureInfo("en-US");
XDocument xDoc = XDocument.Load("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
var cubeNodes = xDoc.Descendants().Where(n => n.Name.LocalName == "Cube" && n.Attribute("currency") != null).ToList();
var currencyRateItems = cubeNodes.Select(node => new
{
Currency = node.Attribute("currency").Value,
Rate = double.Parse(node.Attribute("rate").Value, usCulture)
});
int pageSize = 5, pageCounter = 0;
var pageItems = currencyRateItems.Take(pageSize);
while(pageItems.Count() > 0)
{
foreach (var item in pageItems)
Console.WriteLine(item.Currency + ": " + item.Rate.ToString("N2", usCulture));
Console.WriteLine("Press any key to get the next items...");
Console.ReadKey();
pageCounter++;
// Here's where we use the Skip() and Take() methods!
pageItems = currencyRateItems.Skip(pageSize * pageCounter).Take(pageSize);
}
Console.WriteLine("Done!");
}
}
}
Dat is een heleboel code, maar laten we er even doorheen lopen. In de eerste helft 'parsen' we een publiek toegankelijke XML bron van wisselkoersen. Dit geeft mij de gelegenheid om je een idee te geven van LINQ en XML , wat een erg mooi onderdeel is van het LINQ eco-systeem. We bespreken dit in een ander artikel, maar weet nu al dat we het gebruiken om de belangrijke knooppunten uit de XML bron te trekken en die in anonieme objecten te stoppen, die bestaan uit de naam en de huidige wisselkoers, die we later zullen gebruiken.
We hebben nu een databron van valuta informatie in de currencyRateItems variabele.In de laatste helft van het voorbeeld gebruiken we deze bron om wat eenvoudige paginering te doen. We verwijderen 5 items en vragen de gebruiker om een toets in te drukken voor de volgende vijf (of hoeveel er nog maar over zijn in de bron). We doen dat door de eerste vijf items ervan af te trekken en gebruiken een while 'loop' voor de volgende vijf, tot de bron leeg is. Het pakken van de volgende 5 items wordt gedaan met een combinatie van Skip() enTake(), die de basis waren voor dit artikel.
Samenvatting
The Skip() en Take() methods zijn simpel in het gebruik, maar uiterst nuttig in tal van situaties. Zoals gezegd worden ze vaak samen gebruikt, maar vooral de Take() method kan net zo goed alleen gebruikt worden.