2009-09-25 3 views
9

기본 데이터 저장소 (현재 SQL Server 2005)를 쿼리하는 데 사용되는 WCF 서비스가 있습니다. 이 서비스는 다소 많은 양의 데이터를 반환 할 수 있습니다. ~ 20 개의 속성을 포함하는 우리 엔티티 클래스의 60000+ 인스턴스. 속성은 주로 string, int, DateTime과 같은 프리미티브 (primitives)입니다. 그 계층 구조는별로 깊지 않습니다.많은 양의 데이터가있는 WCF 서비스에 대한 모범 사례가 있습니까?

이 서비스를 사용하는 한 응용 프로그램은 일반적으로 합리적인 수의 엔터티 만 반환하는 쿼리를 만듭니다 (단 몇 인스턴스에서 최대 2,000 개). 그러나 때때로 위에서 언급 한 것처럼 많은 양을 반환하는 쿼리를 생성합니다 (쿼리 데이터를 처리해야하므로 쿼리 기준을 좁힐 수 없습니다).

우리가하고 싶은 것은 클라이언트가 서비스를 호출하고 특정 수의 인스턴스를 다시 가져온 다음 다시 호출하여 다음 청크를 가져올 수있는 일종의 "페이징"기능을 도입하는 것입니다. 전체 결과가 반입됩니다. WCF에 많은 도움이되지는 않았지만,이를 달성하기위한 최선의 방법은 확실하지 않습니다.

염두에 두어야 할 한 가지 사실은 청크를 가져 오는 동안 기본 데이터가 매우 잘 변경 될 수 있다는 것입니다. 나는 이것이 우리에게 문제가되는지 아닌지 잘 모르겠다. (조금은 생각할 필요가있다.) 그렇지만 그렇게 할 수 있기 때문에 특정 상황을 다루는 것에 대한 모든 의견도 환영 받는다.

우리는 전체 결과가 수신되기 전에 데이터 처리를 시작하기를 원하기 때문에 응답 스트리밍을 살펴 보았지만 페이징 샘플도보고 싶습니다.

그래서 짧은 질문 : 이런 종류의 시나리오 (또는 우리가 알고 있어야하는 절대적인 아니오)에 대한 모범 사례가 있습니까?

+1

Fredrik- 당신은 이것을 보았습니다. http://stackoverflow.com/questions/741413/implementing-pager-through-wcf-service- 조금 기본이지만 – RichardOD

+0

@RichardOD : 링크를 이용해 주셔서 감사합니다. 나는 우리가 그보다 낮은 단계에서 이것을 공격 할 필요가 있다고 생각하지만, 실험 시간을 줄 것이다. –

답변

9

스트림 [MessageBodyMember] (및 [MessageHeader]로 전송 된 다른 메타 데이터) 만있는 MessageContract를 사용하여 클라이언트와 서버에서 스트리밍 바인딩 구성을 사용하면 페이징 걱정없이 한 번의 호출로 모든 작업을 수행 할 수 있습니다. 서버 측에서 열거자를 사용하여 스트림을 피드하고 클라이언트에서 나타나는대로 개별 엔티티를 처리하지만 스트림 내에서 자체 프레임을 롤업해야합니다 (예 : DataContractSerializer를 사용하여 스트림에서 수동으로 엔티티 직렬화/비 직렬화 또는 무엇이든). 나는이 일을 해냈지만 훌륭하게 작동하지만 고통스러워.

페이징을 원한다면 스냅 샷 트랜잭션과 함께 세션 넘치는 WCF 채널을 사용하는 것이 가장 쉬운 방법입니다 (SQL Server 나 엔티티 원본을 지원하는 다른 항목을 사용하는 경우). 첫 번째 요청에서 스냅 샷 tx를 시작한 다음 tx의 수명을 세션에 연결하여 페이지 요청 사이의 안정된 데이터 그림을 봅니다. 세션이 닫히면 tx가 해제됩니다. 클라이언트가 예기치 않게 연결이 끊어진 경우). 그런 다음 클라이언트는보고있는 마지막 키 값 + 원하는 레코드 수 (maxReceivedMessageSize-가 많은 헤드 룸을 남겨 둡니다)를 요청합니다. 스냅 샷을 작성했기 때문에 변경 사항에 대해 걱정할 필요가 없습니다. 덤프 기간 동안 일관된보기를 볼 수 있습니다. 다운로드 중간에서 변경되지 않도록 원본 데이터를 스냅 샷으로 저장할 수 없으면 수명이 훨씬 더 어려워집니다. 항상 수행 가능하지만이를 위해 설계하는 것은 데이터에 매우 중요합니다.

+0

입력 해 주셔서 감사합니다. 스냅 샷 거래 아이디어를 살펴 보겠습니다. 이제는 일부 서비스가 페이징을 지원하기 위해 Linq-to-SQL로 옮겨 갈 수도 있습니다. 나는 그 아이디어들이 결합 될 수 있는지를 점검 할 것이고 그것은 이상적 일 것이다. –

+0

그들은 모든 것을 위해 LINQ to SQL을 사용할 수 있습니다.스냅 샷의 유일한 트릭은 모든 레코드 (및 관련 데이터)를 처음에 한 번 만지면되지만 스냅 샷에 포함 시키려면 클라이언트에 실제로 반환하지 않아야한다는 것입니다. 이산 SQL 명령은 아마도 더 좋을 것입니다. – nitzmahone

관련 문제