문제

어떻게 당신은 페이지를 통해 수집 LINQ 에서 주어지는 당신이 startIndexcount?

도움이 되었습니까?

해결책

몇 달이 다시 내가 쓴 블로그 게시물에 대해 유창한 인터페이스와 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.

다른 팁

그것은 아주 간단한 SkipTake 장 방법이 있습니다.

var query = from i in ideas
            select i;

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

내가 해결이 조금 다르게 무엇보다 사람들은 다른 사람들이 내가 내 자신을 만들기 위해 매기기와 함께 리피터입니다.그래서 내가 처음 만들의 컬렉션 페이지 번호는 수집하는 항목의 나이:

// 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>).이것은 당신이 그것을 할 수있는 방법을 사용하여 SkipTake 과 함께 선택하여 인덱스 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 를 구현하는 페이징이다.사실,그것은 간단 LINQ-알고리즘은 위와 같지만,성능이 향상:

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() 에 대한 여러 번에"식"방식은,그것이 정말로 저장"pointer"의 반복,그것이 마지막으로 건너뜁니다.-대신 원래 순서 될 것입니다 앞으로 로드 건너 통화로 이어질 것입니다"이 소요"이미"사용된"페이지요.-할 수 있음을 증명할 수 있습니다 자신을 만들 때 순서 ideas 그래서 그것은 수익률을 부작용이 있습니다.->경우에도 건너는 10~20 20~30 하고 싶은 프로세스 40+,당신은 모든 측면을 효과 10~30 실행되는,다시 시작하기 전에 반복 40+.변형을 사용하여 IEnumerable's 직접 인터페이스,대신의 위치를 기억하고의 논리적인 페이지므로 명시적인 건너 필요하고 부작용이 반복되지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top