LINQ ile bir koleksiyon sayfalama

oy
69

Nasıl bir olduğu kabul edilirse LINQ bir koleksiyon aracılığıyla size sayfasını yapmak startIndexve count?

Oluştur 01/08/2008 saat 14:20
kaynak kullanıcı
Diğer dillerde...                            


4 cevaplar

oy
61

Bu çok basit Skipve Takeuzatma yöntemlerine.

var query = from i in ideas
            select i;

var paggedCollection = query.Skip(startIndex).Take(count);
Cevap 01/08/2008 saat 14:22
kaynak kullanıcı

oy
38

Birkaç ay önce ben bir uzantısı metodunu kullanıyoruz Akıcı Arayüzleri ve LINQ hakkında bir blog yazısı yazdı IQueryable<T>bir LINQ koleksiyonu Sayfalara ayırma aşağıdaki doğal bir şekilde sağlamak için ve başka bir sınıfta.

var query = from i in ideas
            select i;
var pagedCollection = query.InPagesOf(10);
var pageOfIdeas = pagedCollection.Page(2);

Sen MSDN kod galeride Sayfasından kodunu alabilirsiniz: Boru hatları, Filtreler, Akıcı API ve LINQ to SQL .

Cevap 07/08/2008 saat 09:22
kaynak kullanıcı

oy
12

Ben bir tekrarlayıcı ile, kendi paginator yapmak zorunda kaldı diğerleri var olandan farklı bu biraz çözdü. Bu yüzden ilk ben öğelerin toplanması için sayfa numaraları bir koleksiyon yaptı:

// assumes that the item collection is "myItems"

int pageCount = (myItems.Count + PageSize - 1) / PageSize;

IEnumerable<int> pageRange = Enumerable.Range(1, pageCount);
   // pageRange contains [1, 2, ... , pageCount]

Bu kullanma Kolayca "sayfalar" koleksiyonu olarak öğe koleksiyonu bölüm olabilir. Bu durumda bir sayfa öğelerinin sadece topluluğudur ( IEnumerable<Item>). Bu kullanarak bunu yapabilirsiniz nasıl Skipve Takegelen indeksi seçerek birlikte pageRangeyukarıda oluşturuldu:

IEnumerable<IEnumerable<Item>> pageRange
    .Select((page, index) => 
        myItems
            .Skip(index*PageSize)
            .Take(PageSize));

Tabii ki ek bir koleksiyon olarak her sayfayı işlemek ama repeaters iç içe eğer örneğin zorunda sonra bu aslında işlemek kolaydır.


Tek satırlık TLDR sürümü bu olacaktır:

var pages = Enumerable
    .Range(0, pageCount)
    .Select((index) => myItems.Skip(index*PageSize).Take(PageSize));

Hangisi bu şekilde kullanılabilir:

for (Enumerable<Item> page : pages) 
{
    // handle page

    for (Item item : page) 
    {
        // handle item in page
    }
}
Cevap 20/03/2012 saat 13:52
kaynak kullanıcı

oy
9

Bu soru biraz eski, ama (kullanıcı etkileşimi dahil) tüm prosedürü gösterir benim çağrı algoritması sonrası istedim.

const int pageSize = 10;
const int count = 100;
const int startIndex = 20;

int took = 0;
bool getNextPage;
var page = ideas.Skip(startIndex);

do
{
    Console.WriteLine("Page {0}:", (took / pageSize) + 1);
    foreach (var idea in page.Take(pageSize))
    {
        Console.WriteLine(idea);
    }

    took += pageSize;
    if (took < count)
    {
        Console.WriteLine("Next page (y/n)?");
        char answer = Console.ReadLine().FirstOrDefault();
        getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);

        if (getNextPage)
        {
            page = page.Skip(pageSize);
        }
    }
}
while (getNextPage && took < count);

Eğer gösteriden sonra ve üretim kodu olan, ancak, hepimiz performanstan sonra yukarıda gösterilen değil, altta yatan gibi, sen LINQ en çağrıyı kullanmaması gerektiğini konum IEnumeratorKendini çağrı uygulamaktır. Nitekim olarak, yukarıda gösterilen LINQ-algoritma, ancak daha fazla ölçülebilir kadar basittir:

const int pageSize = 10;
const int count = 100;
const int startIndex = 20;

int took = 0;
bool getNextPage = true;
using (var page = ideas.Skip(startIndex).GetEnumerator())
{
    do 
    {
        Console.WriteLine("Page {0}:", (took / pageSize) + 1);

        int currentPageItemNo = 0;
        while (currentPageItemNo++ < pageSize && page.MoveNext())
        {
            var idea = page.Current;
            Console.WriteLine(idea);
        }

        took += pageSize;
        if (took < count)
        {
            Console.WriteLine("Next page (y/n)?");
            char answer = Console.ReadLine().FirstOrDefault();
            getNextPage = default(char) != answer && 'y' == char.ToLowerInvariant(answer);
        }
    }
    while (getNextPage && took < count);
}

Açıklama: kullanmanın olumsuz Skip()bir "basamaklı bir biçimde" birden çok kez gerçekten son atlandı yineleme, bir "işaretçi" saklamaz olmasıdır. - Yerine orijinal dizisi ön yüklemeli tekrar tekrar "alıcı" zaten "tüketilen" sayfalara yönlendirme yapar atlama görüşmeleri, birlikte olacaktır. - Eğer diziyi oluştururken, kendine kanıtlayabilirim ideasyan etkileri verir, böylece. -> Eğer 10-20 20-30 atlanır ve 40+ işlemek istiyorum olsanız bile, size 40 + yineleme başlamadan önce, yine yürütülmektedir 10-30 tüm yan etkilerini göreceksiniz. Kullanarak varyant IEnumerabledoğrudan ler' arayüzünü yerine geçen mantıksal sayfanın sonunda pozisyonunu hatırlar, böylece hiçbir açık atlama gereklidir ve yan etkiler tekrar edilmeyecektir.

Cevap 16/07/2011 saat 21:07
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more