2009-09-25 30 views
9

Chúng tôi có dịch vụ WCF được sử dụng để truy vấn kho lưu trữ dữ liệu cơ bản (SQL Server 2005 ngay bây giờ). Dịch vụ này có thể trả về một lượng lớn dữ liệu; 60000+ phiên bản của lớp thực thể chứa ~ 20 thuộc tính. Các thuộc tính chủ yếu là nguyên thủy như chuỗi, int, DateTime với một cặp vợ chồng chỉ vào các thực thể khác có thể lần lượt trỏ vào những người khác; những hệ thống phân cấp đó không sâu lắm.Thực hành tốt nhất cho dịch vụ WCF với lượng lớn dữ liệu?

Một ứng dụng đang sử dụng dịch vụ này thường sẽ tạo các truy vấn trả về chỉ một số lượng thực thể hợp lý (chỉ từ một vài trường hợp lên đến vài nghìn). Nhưng đôi khi nó sẽ thực hiện một truy vấn sẽ trả về một số lượng lớn như đã nêu ở trên (và nó sẽ cần phải xử lý dữ liệu đó, do đó thu hẹp các tiêu chí truy vấn không phải là một tùy chọn).

Điều chúng tôi muốn làm là giới thiệu một số chức năng "phân trang", nơi khách hàng có thể gọi dịch vụ và nhận lại một số trường hợp nhất định, sau đó gọi lại và lấy đoạn tiếp theo và tiếp tục, cho đến khi kết quả đầy đủ được tìm nạp. Đã không làm việc rất nhiều với WCF, tôi không hoàn toàn chắc chắn về cách tốt nhất để đạt được điều này.

Một điều cần lưu ý là dữ liệu cơ bản có thể thay đổi rất nhiều trong khi tìm nạp các khối. Tôi không hoàn toàn chắc chắn nếu điều này là một vấn đề đối với chúng tôi hay không (cần phải invesigat rằng một chút), nhưng nó có thể được, vì vậy bất kỳ đầu vào về xử lý tình hình cụ thể cũng được chào đón.

Chúng tôi đã bắt đầu xem xét truyền trực tuyến phản hồi, nhưng cũng muốn xem mẫu phân trang, vì chúng tôi có thể muốn bắt đầu xử lý dữ liệu trước khi nhận được kết quả đầy đủ.

Vì vậy, câu hỏi ngắn gọn: có cách nào hay nhất cho loại kịch bản này (hoặc bất kỳ sự không tuyệt đối nào mà chúng ta nên biết)?

+1

Fredrik- bạn đã thấy điều này- http://stackoverflow.com/questions/741413/implementing-pager-through-wcf-service- một chút cơ bản mặc dù – RichardOD

+0

@RichardOD: cảm ơn vì liên kết. Tôi nghĩ chúng ta cần tấn công ở mức độ thấp hơn thế, nhưng tôi sẽ cho nó một thời gian thử nghiệm. –

Trả lời

9

Sử dụng cấu hình ràng buộc trực tuyến trên máy khách và máy chủ với MessageContract chỉ có Luồng [MessageBodyMember] (và bất kỳ siêu dữ liệu nào khác được gửi dưới dạng [MessageHeader]) sẽ cho phép bạn thực hiện toàn bộ cuộc gọi mà không phải lo lắng về phân trang (chỉ cần sử dụng một điều tra viên ở phía máy chủ để nạp luồng và xử lý các thực thể riêng lẻ khi chúng xuất hiện trên máy khách), nhưng bạn phải cuộn khung của riêng mình trong luồng (ví dụ, sắp xếp/deserialize các thực thể theo cách thủ công trên luồng với DataContractSerializer hay bất cứ cái gì). Tôi đã làm điều này, và nó hoạt động rất tốt, nhưng đó là một nỗi đau.

Nếu bạn muốn phân trang, cách dễ dàng là sử dụng kênh WCF phiên cùng với giao dịch chụp nhanh (nếu bạn đang sử dụng SQL Server hoặc một thứ khác hỗ trợ chúng làm nguồn thực thể). Bắt đầu ảnh chụp tx trên yêu cầu đầu tiên, sau đó gắn kết cuộc sống của tx vào phiên, để bạn nhìn vào một hình ảnh ổn định của dữ liệu giữa các yêu cầu trang - tx sẽ được giải phóng khi phiên được đóng (hoặc lần ra, nếu khách hàng bị ngắt kết nối bất ngờ). Sau đó, khách hàng yêu cầu giá trị khóa cuối cùng mà nó thấy + số lượng bản ghi mà nó muốn (cẩn thận là maxReceivedMessageSize- leave LOTS của khoảng không). Vì bạn đang ở trong ảnh chụp nhanh, bạn không phải lo lắng về các thay đổi - bạn sẽ thấy một chế độ xem nhất quán trong khoảng thời gian kết xuất. Nếu bạn không thể chụp nhanh dữ liệu nguồn của bạn để ngăn không cho nó thay đổi giữa tải xuống, cuộc sống khó hơn rất nhiều. Luôn luôn có thể thực hiện được, nhưng thiết kế cho điều đó rất cụ thể đối với dữ liệu.

+0

Cảm ơn bạn đã nhập. Tôi sẽ xem xét ý tưởng giao dịch chụp nhanh. Có vẻ như chúng tôi đã chuyển một số dịch vụ sang Linq-to-sql để hỗ trợ phân trang. Tôi sẽ kiểm tra xem những ý tưởng đó có thể được kết hợp, điều đó sẽ là lý tưởng. –

+0

Chúng ta có thể sử dụng LINQ to SQL cho mọi thứ.Bí quyết duy nhất với ảnh chụp nhanh là bạn cần phải chạm vào tất cả các bản ghi (và dữ liệu liên quan) một lần ngay từ đầu, (nhưng không thực sự trả lại nó cho máy khách) để đưa nó vào ảnh chụp nhanh. Một lệnh SQL rời rạc có lẽ sẽ tốt hơn cho điều đó. – nitzmahone

Các vấn đề liên quan