Correlazione basata sul contenutoContent Based Correlation

Quando i servizi flusso di lavoro comunicano con client e altri servizi, sono spesso presenti alcuni dati nei messaggi scambiati che correlano in modo univoco un messaggio a una particolare istanza.When workflow services communicate with clients and other services, often there is some data in the exchanged messages that uniquely relates a message to a particular instance. La correlazione basata sul contenuto usa questi dati nel messaggio, ad esempio un numero cliente o un ID dell'ordine, per indirizzare messaggi all'istanza del flusso di lavoro appropriata.Content-based correlation uses this data in the message, such as a customer number or order ID, to route messages to the proper workflow instance. In questo argomento viene illustrato come usare la correlazione basata sul contenuto nei flussi di lavoro.This topic explains how to use content-based correlation in workflows.

Utilizzo della correlazione basata sul contenutoUsing Content-Based Correlation

La correlazione basata sul contenuto viene usata se un servizio flusso di lavoro dispone di più metodi a cui viene eseguito l'accesso da parte di un solo client e una parte dei dati nei messaggi scambiati identifica l'istanza desiderata.Content-based correlation is used when a workflow service has multiple methods that are accessed by a single client and a piece of data in the exchanged messages identifies the desired instance.

Nota

La correlazione basata sul contenuto risulta utile se non è possibile usare la correlazione del contesto in quanto l'associazione non rientra tra quelle di scambio del contesto supportate.Content-based correlation is useful when context correlation cannot be used because the binding is not one of the supported context exchange bindings. Per ulteriori informazioni sulla correlazione del contesto, vedere lo scambio del contesto.For more information about context correlation, see Context Exchange.

Ogni attività di messaggistica usata in queste comunicazioni deve specificare il percorso dei dati nel messaggio che identificano in modo univoco l'istanza.Each messaging activity used in these communications must specify the location of the data in the message that uniquely identifies the instance. A tale scopo viene fornito un elemento MessageQuerySet, che usa un elemento QueryCorrelationInitializer o CorrelatesOn, che esegue una query nel messaggio per una o più parti di dati che identificano in modo univoco l'istanza.This is done by providing a MessageQuerySet, using either a QueryCorrelationInitializer or CorrelatesOn, that queries the message for the piece or pieces of data that uniquely identify the instance.

Avviso

Per i dati usati per l'identificazione dell'istanza viene generato un hash in una chiave di correlazione.The data that is used to identify the instance is hashed into a correlation key. È necessario verificare che i dati usati per la correlazione siano univoci. In caso contrario si potrebbero verificare conflitti nella chiave con hash e i messaggi potrebbero essere indirizzati in modo errato.Care must be taken to ensure that the data used for correlation is unique or else collisions in the hashed key could occur and cause messages to be misrouted. Una correlazione basata esclusivamente su un nome di cliente può ad esempio generare un conflitto, poiché possono esistere più clienti con lo stesso nome.For example, a correlation based solely on a customer name may cause a collision because there may be multiple customers with the same name. Non usare i due punti (:) come parte dei dati per correlare il messaggio, poiché vengono già usati per delimitare il valore e la chiave della query del messaggio per formattare la stringa per la quale verrà generato un hash.The colon (:) should not be used as part of the data used to correlate the message because it is already used to delimit the message query’s key and value to form the string that is subsequently hashed.

Nell'esempio seguente, il primo Receive / SendReply in un servizio flusso di lavoro restituisce un OrderId, che viene quindi passato nuovamente dal client alla chiamata al seguente Receive attività nel servizio del flusso di lavoro.In the following example, the initial Receive/SendReply in a workflow service returns an OrderId, which is then passed back by the client on the call to the following Receive activity in the workflow service.

Variable<string> OrderId = new Variable<string>();
Variable<string> Item = new Variable<string>();
Variable<CorrelationHandle> OrderIdHandle = new Variable<CorrelationHandle>();

Receive StartOrder = new Receive
{
    CanCreateInstance = true,
    ServiceContractName = "IOrderService",
    OperationName = "StartOrder"
};

SendReply ReplyToStartOrder = new SendReply
{
    Request = StartOrder,
    Content = SendParametersContent.Create(new Dictionary<string, InArgument>
        { { "OrderId", new InArgument<string>((env) => OrderId.Get(env)) } }),
    CorrelationInitializers =
    {
        new QueryCorrelationInitializer
        {
            CorrelationHandle = OrderIdHandle,
            MessageQuerySet = new MessageQuerySet
            {
                {
                    "OrderId", 
                    new XPathMessageQuery("sm:body()/tempuri:StartOrderResponse/tempuri:OrderId")
                }
            }
        }
    }
};

Receive AddItem = new Receive
{
    ServiceContractName = "IOrderService",
    OperationName = "AddItem",
    CorrelatesWith = OrderIdHandle,
    CorrelatesOn = new MessageQuerySet
    {
        {
            "OrderId", 
              new XPathMessageQuery("sm:body()/tempuri:AddItem/tempuri:OrderId")
        }
    },
    Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>
        { { "OrderId", new OutArgument<string>(OrderId) },  
        { "Item", new OutArgument<string>(Item) } })
};

SendReply ReplyToAddItem = new SendReply
{
    Request = AddItem,
    Content = SendParametersContent.Create(new Dictionary<string, InArgument>
        { { "Reply", new InArgument<string>((env) => "Item added: " + Item.Get(env)) } }),
};

// Construct a workflow using StartOrder, ReplyToStartOrder, and AddItem.

Nell'esempio precedente viene mostrata una correlazione basata sul contenuto inizializzata da SendReply.The previous example shows a content-based correlation that is initialized by the SendReply. MessageQuerySet specifica che i dati usati per identificare i messaggi successivi a questo servizio sono di tipo OrderId.The MessageQuerySet specifies that the data used to identify subsequent messages to this service is the OrderId.

SendReply ReplyToStartOrder = new SendReply
{
    Request = StartOrder,
    Content = SendParametersContent.Create(new Dictionary<string, InArgument>
        { { "OrderId", new InArgument<string>((env) => OrderId.Get(env)) } }),
    CorrelationInitializers =
    {
        new QueryCorrelationInitializer
        {
            CorrelationHandle = OrderIdHandle,
            MessageQuerySet = new MessageQuerySet
            {
                {
                    "OrderId", 
                    new XPathMessageQuery("sm:body()/tempuri:StartOrderResponse/tempuri:OrderId")
                }
            }
        }
    }
};

L'attività Receive che successiva a SendReply nel flusso di lavoro segue la correlazione inizializzata da SendReply.The Receive activity that follows the SendReply in the workflow follows the correlation that was initialized by the SendReply. Entrambe le attività condividono lo stesso elemento CorrelationHandle, ma ognuna dispone di specifici elementi MessageQuerySet e XPathMessageQuery che indicano la posizione all'interno del messaggio in cui si trovano i dati di identificazione.Both activities share the same CorrelationHandle, but each one has its own MessageQuerySet and XPathMessageQuery that specifies where the identifying data is in that particular message. Nell'attività che inizializza la correlazione, questo elemento MessageQuerySet viene specificato nella proprietà CorrelationInitializers e, per qualsiasi attività Receive successiva, mediante la proprietà CorrelatesOn.On the activity that initializes the correlation, this MessageQuerySet is specified in the CorrelationInitializers property, and for any following Receive activities, it is specified using the CorrelatesOn property.

Receive AddItem = new Receive
{
    ServiceContractName = "IOrderService",
    OperationName = "AddItem",
    CorrelatesWith = OrderIdHandle,
    CorrelatesOn = new MessageQuerySet
    {
        {
            "OrderId", 
              new XPathMessageQuery("sm:body()/tempuri:AddItem/tempuri:OrderId")
        }
    },
    Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>
        { { "OrderId", new OutArgument<string>(OrderId) },  
        { "Item", new OutArgument<string>(Item) } })
};

Una correlazione basata sul contenuto può essere inizializzata da qualsiasi attività di messaggistica (Send, Receive, SendReply, ReceiveReply) quando i dati vengono propagati come parte di un messaggio.A content-based correlation can be initialized by any messaging activity (Send, Receive, SendReply, ReceiveReply) when the data flows as part of a message. Se questa parte di dati non viene propagata come parte di un messaggio, è possibile inizializzarla in modo esplicito tramite l'attività InitializeCorrelation.If the particular piece of data does not flow as part of a message, then it can be initialized explicitly by using the InitializeCorrelation activity. Se sono necessarie più parti di dati per identificare in modo univoco il messaggio, è possibile aggiungere più query a MessageQuerySet.If multiple pieces of data are required to uniquely identify the message, then multiple queries can be added to the MessageQuerySet. In questi esempi è stato fornito in modo esplicito un elemento CorrelationHandle a ogni attività che usa le proprietà CorrelatesWith o CorrelationHandle, ma se è necessaria una sola correlazione per l'intero flusso di lavoro intero, come in questo caso, in cui tutti gli elementi vengono correlati in OrderId, è sufficiente la gestione dell'handle di correlazione implicita fornita da WorkflowServiceHost.In these examples, a CorrelationHandle was explicitly provided to each of the activities using the CorrelatesWith or CorrelationHandle properties, but if there is only one correlation required for the entire workflow, such as in this example where everything correlates on OrderId, the implicit correlation handle management provided by WorkflowServiceHost is sufficient.

Utilizzo dell'attività InitializeCorrelationUsing the InitializeCorrelation Activity

Nell'esempio precedente l'elemento OrderId è stato propagato al chiamante tramite l'attività SendReply e la correlazione è stata inizializzata in questo punto.In the previous example, the OrderId flowed to the caller through the SendReply activity and this is where the correlation was initialized. È possibile ottenere lo stesso comportamento usando l'attività InitializeCorrelation.The same behavior can be accomplished by using the InitializeCorrelation activity. L'attività InitializeCorrelation usa l'elemento CorrelationHandle e un dizionario di elementi che rappresentano i dati usati per eseguire il mapping del messaggio all'istanza corretta.The InitializeCorrelation activity takes the CorrelationHandle and a dictionary of items that represent the data used to map the message to the correct instance. Per usare l'attività InitializeCorrelation nell'esempio precedente, rimuovere CorrelationInitializers dall'attività SendReply e inizializzare la correlazione usando l'attività InitializeCorrelation.To use the InitializeCorrelation activity in the preceding sample, remove the CorrelationInitializers from the SendReply activity and initialize the correlation using the InitializeCorrelation activity.

Variable<string> OrderId = new Variable<string>();
Variable<string> Item = new Variable<string>();
Variable<CorrelationHandle> OrderIdHandle = new Variable<CorrelationHandle>();

InitializeCorrelation OrderIdCorrelation = new InitializeCorrelation
{
    Correlation = OrderIdHandle,
    CorrelationData = { { "OrderId", new InArgument<string>(OrderId) } }
};

Receive StartOrder = new Receive
{
    CanCreateInstance = true,
    ServiceContractName = "IOrderService",
    OperationName = "StartOrder"
};

SendReply ReplyToStartOrder = new SendReply
{
    Request = StartOrder,
    Content = SendParametersContent.Create(new Dictionary<string, InArgument> { { "OrderId", new InArgument<string>((env) => OrderId.Get(env)) } }),
};

// Other messaging activities omitted...

L'attività InitializeCorrelation viene quindi usata nel flusso di lavoro, dopo il popolamento delle variabili contenenti i dati ma prima dell'attività Receive correlata all'elemento CorrelationHandle inizializzato.The InitializeCorrelation activity is then used in the workflow, after the variables that hold the data are populated but before the Receive activity that correlates with the initialized CorrelationHandle.

// Construct a workflow using OrderIdCorrelation, StartOrder, ReplyToStartOrder,
// and other messaging activities.
Activity wf = new Sequence
{
    Variables =
    {
        OrderId,
        Item,
        OrderIdHandle
    },
    Activities =
    {
        // Wait for a new order.
        StartOrder,
        // Assign a unique identifier to the order.
        new Assign<string>
        {
            To = new OutArgument<string>( (env) => OrderId.Get(env)),
            Value = new InArgument<string>( (env) => Guid.NewGuid().ToString() )
        },
        ReplyToStartOrder,
        // Initialize the correlation.
        OrderIdCorrelation,
        // Wait for an item to be added to the order.
        AddItem,
        ReplyToAddItem
     }
};

Configurazione di query XPath mediante Progettazione flussi di lavoroConfiguring XPath Queries Using the Workflow Designer

Negli esempi precedenti le attività e le query XPath usate nelle query del messaggio sono state specificate nel codice.In the previous examples, the activities and the XPath queries used in the message queries were specified in code. Progettazione flussi di lavoro in Visual Studio 2012Visual Studio 2012 fornisce inoltre la possibilità di generare query XPath dai tipi DataContract per la correlazione basata sul contenuto.The workflow designer in Visual Studio 2012Visual Studio 2012 also provides the ability to generate XPaths from DataContract types for content-based correlation. La prima query XPath nell'esempio precedente è stata configurata per SendReply.The first XPath configured in the previous example was configured for the SendReply.

SendReply ReplyToStartOrder = new SendReply
{
    Request = StartOrder,
    Content = SendParametersContent.Create(new Dictionary<string, InArgument>
        { { "OrderId", new InArgument<string>((env) => OrderId.Get(env)) } }),
    CorrelationInitializers =
    {
        new QueryCorrelationInitializer
        {
            CorrelationHandle = OrderIdHandle,
            MessageQuerySet = new MessageQuerySet
            {
                {
                    "OrderId", 
                    new XPathMessageQuery("sm:body()/tempuri:StartOrderResponse/tempuri:OrderId")
                }
            }
        }
    }
};

Per configurare la query XPath per un'attività di messaggistica in Progettazione flussi di lavoro, selezionare l'attività all'interno dell'utilità.To configure the XPath for a messaging activity in the workflow designer, select the activity in the workflow designer. Se l'attività sta inizializzando la correlazione, come nell'esempio precedente, fare clic sul pulsante con puntini di sospensione per il CorrelationInitializers proprietà il proprietà finestra.If the activity is initializing the correlation, as in the previous example, click the ellipsis button for the CorrelationInitializers property in the Properties window. Consente di visualizzare il Aggiungi inizializzatori di correlazione finestra di dialogo.This displays the Add Correlation Initializers dialog window. Da questa finestra di dialogo è possibile specificare il tipo di correlazione e selezionare il contenuto usato per la correlazione.From this dialog you can specify the correlation type and select the content that is used for the correlation. Il CorrelationHandle variabile viene specificata nel aggiungere inizializzatore casella e il tipo di correlazione e dati usati per la correlazione è selezionato dal query XPath sezione della finestra di dialogo.The CorrelationHandle variable is specified in the Add initializer box, and the correlation type and data used for the correlation is selected from the XPath Queries section of the dialog box.

Finestra di dialogo CorrelationInitializerCorrelationInitializer Dialog

La seconda query XPath nell'esempio precedente è stata configurata nell'attività Receive.The second XPath query in the previous example was configured in the Receive activity.

Receive AddItem = new Receive
{
    ServiceContractName = "IOrderService",
    OperationName = "AddItem",
    CorrelatesWith = OrderIdHandle,
    CorrelatesOn = new MessageQuerySet
    {
        {
            "OrderId", 
              new XPathMessageQuery("sm:body()/tempuri:AddItem/tempuri:OrderId")
        }
    },
    Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>
        { { "OrderId", new OutArgument<string>(OrderId) },  
        { "Item", new OutArgument<string>(Item) } })
};

Per configurare la query XPath per un'attività di messaggistica che non inizializza la correlazione, selezionare l'attività nella finestra di progettazione del flusso di lavoro e quindi fare clic sul pulsante con puntini di sospensione per il CorrelatesOn proprietà il Proprietà finestra.To configure the XPath query for a messaging activity that does not initialize the correlation, select the activity in the workflow designer and then click the ellipsis button for the CorrelatesOn property in the Properties window. Consente di visualizzare il definizione di CorrelatesOn finestra di dialogo.This displays the CorrelatesOn Definition dialog window.

Definizione di CorrelatesOnCorrelatesOn Definition

Da questa finestra di dialogo è possibile specificare il CorrelationHandle e sceglie elementi nel query XPath elenco per compilare la query XPath.From this dialog you specify the CorrelationHandle and choose items in the XPath Queries list to build the XPath query.