Recibir mensajes modificados por datos basados en sondeo de SQL Server mediante el modelo de canal WCF
Puede configurar el adaptador de SQL para recibir mensajes periódicos de cambio de datos para SQL Server tablas o vistas. Puede especificar una instrucción de sondeo que el adaptador ejecuta para sondear la base de datos. La instrucción de sondeo puede ser una instrucción SELECT o un procedimiento almacenado que devuelve un conjunto de resultados.
Para obtener más información sobre cómo admite el sondeo el adaptador, consulte Compatibilidad con llamadas entrantes mediante sondeo.
Importante
Si desea tener más de una operación de sondeo en una sola aplicación, debe especificar una propiedad de conexión InboundID como parte del URI de conexión para que sea única. El identificador de entrada que especifique se agrega al espacio de nombres de la operación para que sea único.
Cómo muestra este tema el sondeo
En este tema, para demostrar cómo el adaptador de SQL admite la recepción de mensajes de cambio de datos, cree una aplicación .NET para la operación de sondeo . Para este tema, especifique PolledDataAvailableStatement como:
SELECT COUNT(*) FROM Employee
PolledDataAvailableStatement debe devolver un conjunto de resultados con la primera celda que contiene un valor positivo. Si la primera celda no contiene un valor positivo, el adaptador no ejecuta la instrucción de sondeo.
Como parte de la instrucción de sondeo, realice las siguientes operaciones:
Seleccione todas las filas de la tabla Empleado.
Ejecute un procedimiento almacenado (MOVE_EMP_DATA) para mover todos los registros de la tabla Employee a una tabla EmployeeHistory.
Ejecute un procedimiento almacenado (ADD_EMP_DETAILS) para agregar un nuevo registro a la tabla Employee. Este procedimiento toma el nombre del empleado, la designación y el salario como parámetros.
Para realizar estas operaciones, debe especificar lo siguiente para la propiedad de enlace PollingStatement :
SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000
Una vez ejecutada la instrucción de sondeo, se seleccionan todos los registros de la tabla Employee y se recibe el mensaje de SQL Server. Una vez que el adaptador ejecuta el MOVE_EMP_DATA procedimiento almacenado, todos los registros se mueven a la tabla EmployeeHistory. A continuación, el ADD_EMP_DETAILS procedimiento almacenado se ejecuta para agregar un nuevo registro a la tabla Employee. La siguiente ejecución de sondeo solo devolverá un único registro. Este ciclo continúa hasta que se cierra el agente de escucha del canal.
Configuración de una consulta de sondeo con las propiedades de enlace del adaptador de SQL
En la tabla siguiente se resumen las propiedades de enlace del adaptador de SQL que se usan para configurar el adaptador para recibir mensajes de cambio de datos. Debe especificar estas propiedades de enlace como parte de la aplicación .NET para sondear.
Binding (propiedad) | Descripción |
---|---|
InboundOperationType | Especifica si desea realizar la operación de entrada Polling, TypedPolling o Notification . El valor predeterminado es Sondeo. |
PolledDataAvailableStatement | Especifica la instrucción SQL que ejecuta el adaptador para determinar si hay datos disponibles para el sondeo. La instrucción SQL debe devolver un conjunto de resultados que consta de filas y columnas. Solo si hay una fila disponible, se ejecutará la instrucción SQL especificada para la propiedad de enlace PollingStatement . |
PollingIntervalInSeconds | Especifica el intervalo, en segundos, en el que el adaptador de SQL ejecuta la instrucción especificada para la propiedad de enlace PolledDataAvailableStatement . El valor predeterminado es 30 segundos. El intervalo de sondeo determina el intervalo de tiempo entre sondeos sucesivos. Si la instrucción se ejecuta dentro del intervalo especificado, el adaptador espera el tiempo restante en el intervalo. |
PollingStatement | Especifica la instrucción SQL que se va a sondear la tabla de base de datos SQL Server. Puede especificar una instrucción SELECT simple o un procedimiento almacenado para la instrucción de sondeo. El valor predeterminado es null. Debe especificar un valor para PollingStatement para habilitar el sondeo. La instrucción de sondeo solo se ejecuta si hay datos disponibles para el sondeo, que viene determinado por la propiedad de enlace PolledDataAvailableStatement . Puede especificar cualquier número de instrucciones SQL separadas por punto y coma. |
PollWhileDataFound | Especifica si el adaptador de SQL omite el intervalo de sondeo y ejecuta continuamente la instrucción SQL especificada para la propiedad de enlace PolledDataAvailableStatement , si los datos están disponibles en la tabla que se están sondeando. Si no hay datos disponibles en la tabla, el adaptador revierte para ejecutar la instrucción SQL en el intervalo de sondeo especificado. El valor predeterminado es false. |
Para obtener una descripción más completa de estas propiedades, vea Leer sobre el adaptador de BizTalk para SQL Server propiedades de enlace del adaptador. Para obtener una descripción completa de cómo usar el adaptador de SQL para sondear SQL Server, lea el resto de este tema.
Consumo del mensaje de solicitud de sondeo
El adaptador invoca la operación de sondeo en el código para sondear la base de datos SQL Server. Es decir, el adaptador envía un mensaje de solicitud de sondeo que recibe a través de una forma de canal IInputChannel. El mensaje de solicitud de sondeo contiene el conjunto de resultados de la consulta especificada por la propiedad de enlace PollingStatement. Puede consumir el mensaje de sondeo de una de estas dos maneras:
Para consumir el mensaje mediante streaming de nodo-valor, debe llamar al método WriteBodyContents en el mensaje de respuesta y pasarlo un XmlDictionaryWriter que implemente streaming de valor de nodo.
Para consumir el mensaje mediante streaming de nodo, puede llamar a GetReaderAtBodyContents en el mensaje de respuesta para obtener un objeto XmlReader.
Acerca de los ejemplos usados en este tema
Los ejemplos de este tema sondean la tabla Employee. En el ejemplo también se usa el MOVE_EMP_DATA y ADD_EMP_DETAILS procedimiento almacenado. Se proporciona un script para generar estos artefactos con los ejemplos. Para obtener más información sobre los ejemplos, vea Ejemplos para el adaptador de SQL. También se proporciona un ejemplo, Polling_ChannelModel, que se basa en este tema, con los ejemplos del adaptador de SQL.
Recepción de mensajes entrantes para la operación de sondeo mediante el modelo de canal WCF
En esta sección se proporcionan instrucciones sobre cómo escribir una aplicación .NET (modelo de canal) para recibir mensajes de sondeo entrantes mediante el adaptador de SQL.
Para recibir mensajes de sondeo del adaptador de SQL
Cree un proyecto de Microsoft Visual C# en Visual Studio. En este tema, cree una aplicación de consola.
En el Explorador de soluciones, agregue referencia a
Microsoft.Adapters.Sql
,Microsoft.ServiceModel.Channels
,System.ServiceModel
ySystem.Runtime.Serialization
.Abra el archivo Program.cs y agregue los siguientes espacios de nombres:
Microsoft.Adapters.Sql
System.ServiceModel
System.ServiceModel.Description
System.ServiceModel.Channels
System.Xml
Especifique un URI de conexión. Para obtener más información sobre el URI de conexión del adaptador, consulte Creación del URI de conexión de SQL Server.
Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
Cree una instancia de SqlAdapterBinding y establezca las propiedades de enlace necesarias para configurar el sondeo. Como mínimo, debe establecer las propiedades de enlace InboundOperationType, PolledDataAvailableStatement y PollingStatement . Para obtener más información sobre las propiedades de enlace usadas para configurar el sondeo, vea Compatibilidad con llamadas entrantes mediante sondeo.
SqlAdapterBinding binding = new SqlAdapterBinding(); binding.InboundOperationType = InboundOperation.Polling; binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE"; binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";
Cree una colección de parámetros de enlace y establezca las credenciales.
ClientCredentials credentials = new ClientCredentials(); credentials.UserName.UserName = "<Enter user name here>"; credentials.UserName.Password = "<Enter password here>"; BindingParameterCollection bindingParams = new BindingParameterCollection(); bindingParams.Add(credentials);
Cree un agente de escucha de canal y ábralo. Para crear el agente de escucha, invoque el método BuildChannelListener<IInputChannel> en SqlAdapterBinding.
IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams); listener.Open();
Obtenga un canal IInputChannel invocando el método AcceptChannel en el agente de escucha y ábralo.
IInputChannel channel = listener.AcceptChannel(); channel.Open();
Invoque Receive en el canal para obtener el siguiente mensaje POLLINGSTMT del adaptador.
Message message = channel.Receive();
Consuma el conjunto de resultados devuelto por la operación POLLINGSTMT. Puede consumir el mensaje mediante XmlReader o XmlDictionaryWriter.
XmlReader reader = message.GetReaderAtBodyContents();
Cierre el canal cuando haya completado el procesamiento de la solicitud.
channel.Close()
Importante
Debe cerrar el canal una vez que haya terminado de procesar la operación POLLINGSTMT. Si no se cierra el canal, puede afectar al comportamiento del código.
Cierre el agente de escucha cuando haya terminado de recibir mensajes modificados de datos.
listener.Close()
Importante
Cerrar el agente de escucha no cierra los canales creados mediante el agente de escucha. Debe cerrar explícitamente cada canal creado mediante el agente de escucha.
Ejemplo
En el ejemplo siguiente se muestra una consulta de sondeo que ejecuta la tabla Employee. La instrucción de sondeo realiza las siguientes tareas:
Selecciona todos los registros de la tabla Employee.
Ejecuta el procedimiento almacenado MOVE_EMP_DATA para mover todos los registros de la tabla Employee a employeeHistory.
Ejecuta el ADD_EMP_DETAILS procedimiento almacenado para agregar un único registro a la tabla Employee.
Los mensajes de sondeo se guardan en
C:\PollingOutput.xml
.
using System;
using Microsoft.Adapters.Sql;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.Xml;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sample started. This sample will poll 5 times and will perform the following tasks:");
Console.WriteLine("Press any key to start polling...");
Console.ReadLine();
IChannelListener<IInputChannel> listener = null;
IInputChannel channel = null;
try
{
TimeSpan messageTimeout = new TimeSpan(0, 0, 30);
SqlAdapterBinding binding = new SqlAdapterBinding();
binding.InboundOperationType = InboundOperation.Polling;
binding.PolledDataAvailableStatement = "SELECT COUNT (*) FROM EMPLOYEE";
binding.PollingStatement = "SELECT * FROM Employee;EXEC MOVE_EMP_DATA;EXEC ADD_EMP_DETAILS John, Tester, 100000";
Uri ConnectionUri = new Uri("mssql://mysqlserver//mydatabase?");
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = "<Enter user name here>";
credentials.UserName.Password = "<Enter password here>";
BindingParameterCollection bindingParams = new BindingParameterCollection();
bindingParams.Add(credentials);
listener = binding.BuildChannelListener<IInputChannel>(ConnectionUri, bindingParams);
listener.Open();
channel = listener.AcceptChannel();
channel.Open();
Console.WriteLine("Channel and Listener opened...");
Console.WriteLine("\nWaiting for polled data...");
Console.WriteLine("Receive request timeout is {0}", messageTimeout);
// Poll five times with the specified message timeout
// If a timeout occurs polling will be aborted
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Polling: " + i);
Message message = null;
XmlReader reader = null;
try
{
//Message is received so process the results
message = channel.Receive(messageTimeout);
}
catch (System.TimeoutException toEx)
{
Console.WriteLine("\nNo data for request number {0}: {1}", i + 1, toEx.Message);
continue;
}
// Get the query results using an XML reader
try
{
reader = message.GetReaderAtBodyContents();
}
catch (Exception ex)
{
Console.WriteLine("Exception :" + ex);
throw;
}
XmlDocument doc = new XmlDocument();
doc.Load(reader);
using (XmlWriter writer = XmlWriter.Create("C:\\PollingOutput.xml"))
{
doc.WriteTo(writer);
Console.WriteLine("The polling response is saved at 'C:\\PollingOutput.xml'");
}
// return the cursor
Console.WriteLine();
// close the reader
reader.Close();
message.Close();
}
Console.WriteLine("\nPolling done -- hit <RETURN> to finish");
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Exception is: " + ex.Message);
if (ex.InnerException != null)
{
Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);
}
}
finally
{
// IMPORTANT: close the channel and listener to stop polling
if (channel != null)
{
if (channel.State == CommunicationState.Opened)
channel.Close();
else
channel.Abort();
}
if (listener != null)
{
if (listener.State == CommunicationState.Opened)
listener.Close();
else
listener.Abort();
}
}
}
}
}
Consulte también
Desarrollo de aplicaciones SQL mediante el modelo de canal WCF