2013-08-28 2 views
0

Skip()Take() 확장명을 사용하여 LINQ를 사용하는 페이징을 쉽게 수행 할 수 있습니다.
동적 인 엔티티 컬렉션 (즉, 두 개의 순차 쿼리간에 변경할 수있는 컬렉션)의 페이징을 수행하는 좋은 방법을 찾기 위해 꽤 오랜 시간 동안 저의 머리를 긁어 왔습니다.페이징 동적 쿼리 결과

은 페이징없이 MyEntity의 20 개 개체를 반환한다고 가정합니다.
다음 두 줄은 results1results2에 데이터 집합의 모든 개체가 채워지는 두 개의 DB 히트를 트리거합니다.

List<MyEntity> results1 = query.Take(10).ToList(); 
List<MyEntity> results2 = query.Skip(10).Take(10).ToList(); 

는 이제 데이터가 동적 가정하자, 새로운 MyEntity하는 두 개의 쿼리 사이, 원래 쿼리가 페이지에 새 개체를 배치 할 수있는 방법으로 DB에 삽입됩니다.
그런 경우 results2 목록에는 results1,
에 존재하는 엔티티가 포함되어 결과를 중복하여 소비자에게 보냅니다. 첫 페이지에서 레코드를 가정

했다 그것은 원래 results2에 표시해야한다 기록 누락됩니다,을 삭제.

이전 페이지에서 검색되지 않은 레코드가 있는지 확인하는 쿼리에 Where() 절을 추가하는 방법에 대해 생각했지만 두 번째 시나리오에서는 도움이되지 않습니다.

쿼리 실행의 타임 스탬프를 기록하고 각 엔터티에 LastUpdatedTimestamp을 첨부하고 이전 페이지 요청 후에 변경된 엔터티를 필터링하는 것에 대해 생각했습니다. 그 방향은 나중에 세 번째 페이지에서 실패합니다 ...

어떻게 정상적으로 수행됩니까?
DB의 이전 스냅 샷에 대해 쿼리를 실행하는 방법이 있습니까?

편집 : 배경은 간단한 GET 요청에 응답하여 엔터티 목록을 검색하는 Asp.NET MVC WebApi 서비스입니다. 클라이언트는 엔티티의 페이지를 검색하여 사용자에게 제공합니다. 아래로 스크롤하면 클라이언트는 서비스에 다른 요청을 보내 사용자에게 이미 제시된 첫 번째 페이지에 추가해야하는 다른 엔터티 페이지를 검색합니다.

+0

데이터가 소비/표시되는 방식은 무엇입니까? 그리고 사용자는 당신이 말하는 페이징 기능을 어떻게 사용합니까? 몇 가지 컨텍스트가 유스 케이스에 맞는 솔루션을 찾는 데 도움이 될 것이라고 생각합니다. – DavidN

+0

고맙습니다. 제 편집 내용을 참조하십시오. 추가 할 수있는 사항이 있으면 알려주십시오. – Liel

+0

오래된 게시물을 되살려 죄송합니다. 문제를 해결할 수 있습니까? 그렇다면 어떻게 생각하세요? – Mese

답변

0

이 문제를 해결하는 한 가지 방법은 첫 번째 쿼리의 TimeStamp를 유지하고 그 시간 이후에 추가 된 결과를 제외하는 것입니다. 그러나이 솔루션은 데이터를 "부실한"상태로 만듭니다. 즉, 특정 시점에 데이터가 고정되어 있습니다. 데이터를 수행해야하는 아주 좋은 이유가 없으면 일반적으로 나쁜 아이디어입니다.

이 작업을 수행하는 또 다른 방법은 모든 개체의 목록을 메모리에 저장 한 다음 한 번에 특정 수의 결과 만 표시하는 것입니다.

List<Entity> _list; 
public class SomeCtor() 
{ 
    _list = _db.Entities.ToList(); 
} 
public List<Entity> GetFirst10 
{ 
    get 
    { 
     return _list.Take(10); 
    } 
} 
public List<Entity> GetSecond10 
{ 
    get 
    { 
     return _list.Skip(10).Take(10); 
    } 
} 
+0

답변 해 주셔서 감사합니다. 두 가지 옵션을 사용하면 웹 서버에서 적절한 구현이 아닌 것으로 판단되는 WebApi 서비스가 상태로 가득 차게됩니다. – Liel

+1

원하는 기능이 상태 저장이며, 이는 잘못된 생각입니다. 일반적으로 무국적자로 남아 있기를 원한다면 이것을 구현하지 않을 것입니다. –