سؤال

كيف يمكنك الصفحة من خلال مجموعة في LINQ بالنظر إلى أن لديك startIndex و count?

هل كانت مفيدة؟

المحلول

قبل عدة أشهر كتبت بلوق وظيفة حول بطلاقة واجهات LINQ التي تستخدم امتداد الأسلوب على IQueryable<T> و فئة أخرى لتوفير الطبيعية التالية طريقة ترقيم صفحات على LINQ جمع.

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

يمكنك الحصول على رمز من معرض رمز MSDN الصفحة: خطوط, فلاتر, يجيد API و LINQ to SQL.

نصائح أخرى

وهو بسيط جدا مع Skip و Take طرق الإرشاد.

var query = from i in ideas
            select i;

var paggedCollection = query.Skip(startIndex).Take(count);

لقد حللت هذا بشكل مختلف قليلا عن ما الآخرين كما كان لي لجعل بلدي paginator مع مكرر.حتى قدمت أول مجموعة من أرقام الصفحات على مجموعة من العناصر التي لدي:

// 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]

باستخدام هذا أنا يمكن بسهولة تقسيم البند مجموعة إلى مجموعة من "الصفحات".صفحة في هذه الحالة هو مجرد مجموعة من العناصر (IEnumerable<Item>).هذا كيف يمكنك أن تفعل ذلك باستخدام Skip و Take جنبا إلى جنب مع اختيار مؤشر من pageRange التي تم إنشاؤها أعلاه:

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

بالطبع لديك للتعامل مع كل صفحة إضافية جمع ولكن على سبيل المثالإذا كنت التعشيش الراسبين ثم هذا هو في الواقع من السهل التعامل معها.


على بطانة واحدة TLDR الإصدار سيكون هذا:

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

والتي يمكن أن تستخدم هذه:

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

    for (Item item : page) 
    {
        // handle item in page
    }
}

هذا السؤال هو إلى حد ما من العمر ، ولكن أردت أن ما الترحيل الخوارزمية التي يظهر الإجراء بأكمله (بما في ذلك تفاعل المستخدم).

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

ومع ذلك ، إذا كنت بعد الأداء في الإنتاج رمز كلنا بعد الأداء لا يجب استخدام LINQ هو ترحيل الصفحات كما هو مبين أعلاه ، وإنما الأساسية IEnumerator لتنفيذ الترحيل نفسك.في الواقع, أنها بسيطة كما ينق-خوارزمية هو مبين أعلاه ، ولكن أكثر performant:

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

التفسير:الجانب السلبي من استخدام Skip() عدة مرات في "المتتالية بطريقة" هو أنه لا حقا متجر "مؤشر" من التكرار ، حيث كان آخر تخطي.- بدلا تسلسل الأصلي سوف تكون مثقلة مع تخطي المكالمات ، والتي سوف تؤدي إلى "المستهلكة" سبق "المستهلكة" صفحات مرارا وتكرارا.- كنت تستطيع أن تثبت نفسك ، عند إنشاء تسلسل ideas بحيث ينتج آثار جانبية.-> حتى إذا كان لديك تخطي 10-20 و 20-30 وتريد أن العملية 40+ سترى جميع الآثار الجانبية من 10-30 يتم تنفيذه مرة أخرى ، قبل البدء بالتكرار 40+.البديل باستخدام IEnumerable's واجهة مباشرة, بدلا من ذلك سوف تتذكر الموقف من نهاية آخر صفحة منطقية, لذا لا صريحة تخطي مطلوب والآثار الجانبية لن تتكرر.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top