TOC

This article is currently in the process of being translated into Russian (~98% done).

LINQ:

Limiting data: the Take() & Skip() methods

До сих пор в этой главе руководства по LINQ мы обнаружили несколько способов работы с источниками данных с использованием LINQ. Теперь пришло время посмотреть, как мы можем ограничить объем данных для работы. Это особенно полезно при использовании базы данных в качестве источника данных, поскольку она часто включает в себя огромное количество строк, извлечение которых требует больших ресурсов.

Методы, которые мы обсудим в этой статье, называются Take() и Skip(), и в сочетании они отлично подходят для выполнения таких вещей, как разбивка на страницы на веб-сайте. На самом деле, они часто используются вместе, но, конечно, их можно использовать и по отдельности. Метод Take() даст вам X количество элементов из источника данных, в то время как Skip() позволит вам игнорировать первые X элементов. Простой пример будет выглядеть следующим образом:

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);

Мы создаем простой список имен, а затем для вывода пропускаем первое имя (Skip(1)), а затем берем следующие два имени (Take (2)), в основном оставляя нам только два средних имени из списка.

Базовая разбивка на страницы с помощью Skip() и Take()

Как вы можете видеть, оба метода Take() и Skip () очень просты в использовании, но их интереснее продемонстрировать с большим количеством данных, чем мы использовали ранее, поэтому я взял на себя смелость создать немного более сложный пример, который лучше продемонстрирует, как эти методы могут помочь вам. Во-первых, вот код для этого:

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!");
   
}
    }
}

Это довольно большой фрагмент кода, но давайте пробежимся по нему. В первой половине мы проанализируем общедоступный XML-источник курсов обмена валют. Это дает мне возможность кратко показать вам LINQ to XML, который является очень интересной частью экосистемы LINQ. Мы обсудим LINQ to XML в другой статье, но пока просто знайте, что мы используем его для извлечения важных узлов из источника XML и помещения их в анонимные объекты, состоящие из названия и текущего обменного курса валюты, которые мы будем использовать позже.

Теперь у нас есть хороший источник данных о валюте в переменной currency Rate Items. В последней половине примера мы используем этот источник для выполнения некоторой простой разбивки на страницы - мы просто извлекаем 5 записей, а затем просим пользователя нажать клавишу, чтобы получить следующие 5 (или сколько бы их ни осталось в источнике). Мы делаем это, извлекая первые 5 записей, а затем используем цикл while для непрерывного извлечения следующих 5 записей, пока источник не опустеет. Получение следующих 5 записей осуществляется с помощью комбинации Skip() и Take() - вся основа этой статьи.

Summary

Методы Skip() и Take() очень просты в использовании, но, тем не менее, очень полезны во многих ситуациях. Как уже упоминалось, они часто используются вместе, но особенно метод Take() с таким же успехом может использоваться отдельно.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!