2009-09-25 13 views
9

Tenemos un servicio WCF que se utiliza para consultar un almacén de datos subyacente (SQL Server 2005 en este momento). Este servicio puede devolver cantidades bastante grandes de datos; 60000+ instancias de nuestra clase de entidad que contiene ~ 20 propiedades. Las propiedades son en su mayoría primitivas, como string, int, DateTime con un par apuntando a otras entidades que a su vez pueden apuntar a otras; esas jerarquías no son muy profundas sin embargo.¿La mejor práctica para el servicio WCF con grandes cantidades de datos?

Una aplicación que consume este servicio normalmente realizará consultas que devuelven solo un número razonable de entidades (desde unas pocas instancias hasta un par de miles). Pero de vez en cuando hará una consulta que devolverá una gran cantidad como se indicó anteriormente (y deberá procesar esos datos, por lo que no es una opción restringir los criterios de consulta).

Lo que queremos hacer es introducir algún tipo de funcionalidad de "paginación", donde el cliente puede llamar al servicio y recuperar un cierto número de instancias, luego volver a llamar y obtener el siguiente fragmento, etc. se obtiene el resultado completo Al no haber trabajado mucho con WCF, no estoy seguro de la mejor manera de lograrlo.

Una cosa que tal vez se debe tener en cuenta es que los datos subyacentes pueden cambiar al obtener los fragmentos. No estoy seguro de si esto es un problema para nosotros o no (necesitamos investigarlo un poco), pero podría serlo, por lo que cualquier comentario sobre el manejo de esa situación particular también es bienvenido.

Hemos comenzado a buscar la transmisión de la respuesta, pero también nos gustaría ver ejemplos de paginación, ya que es posible que deseemos comenzar a procesar los datos antes de recibir el resultado completo.

Entonces, la pregunta en resumen: ¿hay una mejor práctica para este tipo de escenario (o cualquier no-no absoluta que debemos tener en cuenta)?

+1

Fredrik- has visto esto- http://stackoverflow.com/questions/741413/implementing-pager-through-wcf-service- un poco básico, aunque – RichardOD

+0

@RichardOD: gracias por el enlace. Creo que tenemos que atacar esto en un nivel más bajo que eso, pero le daré un tiempo de experimentación. –

Respuesta

9

Usando una configuración de enlace de transmisión en cliente y servidor con MessageContract que tiene solo un Stream [MessageBodyMember] (y cualquier otro metadato enviado como [MessageHeader] s) le permite hacer todo en una llamada sin preocuparse por paginación (solo use un enumerador en el lado del servidor para alimentar la transmisión y procesar entidades individuales tal como aparecen en el cliente), pero tendría que desplegar su propio encuadre dentro de la transmisión (por ejemplo, serializar/deserializar entidades manualmente en la ruta con DataContractSerializer o lo que sea). He hecho esto, y funciona muy bien, pero es un poco doloroso.

Si desea hacer paginación, la manera más fácil es usar un canal WCF de sesión junto con una transacción de instantánea (si está usando SQL Server u otra cosa que los soporte como origen de entidad). Comience la instantánea tx en la primera solicitud, luego vincule la vida del tx a la sesión, de modo que esté viendo una imagen estable de los datos entre las solicitudes de la página: el tx se lanzará cuando se cierre la sesión (o fuera, si el cliente se desconectó inesperadamente). Luego, el cliente solicita el último valor clave que vio + cuántos registros quiere (teniendo cuidado con maxReceivedMessageSize, deje MUCHOS de margen). Dado que está en una instantánea, no tiene que preocuparse por los cambios; verá una vista coherente durante el tiempo que dure el volcado. Si no puede tomar una instantánea de sus datos de origen para evitar que cambie la descarga media, la vida es mucho más difícil. Siempre factible, pero diseñar para eso es muy específico para los datos.

+0

Gracias por su contribución. Analizaré la idea de la transacción instantánea. Tal como se ve ahora, es posible que para algunos de los servicios nos traslademos a Linq-a-sql para soportar paginación. Comprobaré si esas ideas se pueden combinar, lo que sería ideal. –

+0

Pueden usar LINQ to SQL para todo.El único truco con la instantánea es que deberá tocar todos los registros (y datos relacionados) una vez al principio (pero no devolverlos al cliente) para incluirlo en la instantánea. Un comando SQL discreto probablemente sería mejor para eso. – nitzmahone

Cuestiones relacionadas