Operazioni del servizio di chiamata (WCF Data Services)Calling Service Operations (WCF Data Services)

Protocollo OData (Open Data)Open Data Protocol (OData) definisce operazioni del servizio per un servizio dati.The Protocollo OData (Open Data)Open Data Protocol (OData) defines service operations for a data service. WCF Data ServicesWCF Data Services consente di definire tali operazioni come metodi sul servizio dati. enables you to define such operations as methods on the data service. Allo stesso modo di altre risorse del servizio dati, queste operazioni del servizio vengono indirizzate mediante URI.Like other data service resources, these service operations are addressed by using URIs. Un'operazione del servizio può restituire raccolte di tipi di entità, singole istanze del tipo di entità e tipi primitivi, ad esempio Integer e stringa.A service operation can return collections of entity types, single entity type instances, and primitive types, such as integer and string. Un'operazione del servizio può restituire anche null (Nothing in Visual Basic).A service operation can also return null (Nothing in Visual Basic). La libreria client WCF Data ServicesWCF Data Services può essere usata per accedere a operazioni del servizio che supportano richieste HTTP GET.The WCF Data ServicesWCF Data Services client library can be used to access service operations that support HTTP GET requests. Questi tipi di operazioni del servizio sono definiti come metodi a cui vengono applicati oggetti WebGetAttribute.These kinds of service operations are defined as methods that have the WebGetAttribute applied. Per ulteriori informazioni, vedere operazioni del servizio.For more information, see Service Operations.

Le operazioni del servizio sono esposte nei metadati restituiti da un servizio dati che implementa ODataOData.Service operations are exposed in the metadata returned by a data service that implements the ODataOData. Nei metadati le operazioni del servizio vengono rappresentate come elementi FunctionImport.In the metadata, service operations are represented as FunctionImport elements. In caso di generazione di un oggetto DataServiceContext fortemente tipizzato, questo elemento viene ignorato dagli strumenti di aggiunta riferimento al servizio e DataSvcUtil.exe.When generating the strongly-typed DataServiceContext, the Add Service Reference and DataSvcUtil.exe tools ignore this element. Per questo motivo, nel contesto non sarà disponibile alcun metodo che consenta di chiamare direttamente un'operazione di servizio.Because of this, you will not find a method on the context that can be used to call a service operation directly. Per chiamare operazioni di servizio, è tuttavia possibile procedere in uno dei due modi seguenti usando il client WCF Data ServicesWCF Data Services:However, you can still use the WCF Data ServicesWCF Data Services client to call service operations in one of these two ways:

Considerazioni per la chiamata di operazioni del servizioConsiderations for Calling Service Operations

Le considerazioni seguenti si applicano quando si usa il client WCF Data ServicesWCF Data Services per chiamare operazioni di servizio.The following considerations apply when using the WCF Data ServicesWCF Data Services client to call service operations.

  • Quando si accede al servizio dati in modo asincrono, è necessario utilizzare l'equivalente asincrona BeginExecute / EndExecute metodi su DataServiceContext o BeginExecute / EndExecute metodi su DataServiceQuery<TElement>.When accessing the data service asynchronously, you must use the equivalent asynchronous BeginExecute/EndExecute methods on DataServiceContext or the BeginExecute/EndExecute methods on DataServiceQuery<TElement>.

  • La libreria client WCF Data ServicesWCF Data Services non è in grado di materializzare i risultati da un'operazione del servizio che restituisce una raccolta di tipi primitivi.The WCF Data ServicesWCF Data Services client library cannot materialize the results from a service operation that returns a collection of primitive types.

  • La libreria client WCF Data ServicesWCF Data Services non supporta la chiamata a operazioni del servizio POST.The WCF Data ServicesWCF Data Services client library does not support calling POST service operations. Operazioni del servizio chiamate da HTTP POST sono definite tramite WebInvokeAttribute con il parametro Method="POST".Service operations that are called by an HTTP POST are defined by using the WebInvokeAttribute with the Method="POST" parameter. Per chiamare un'operazione del servizio tramite una richiesta HTTP POST, è necessario usare un oggetto HttpWebRequest.To call a service operation by using an HTTP POST request, you must instead use an HttpWebRequest.

  • Non è possibile usare CreateQuery per chiamare un'operazione del servizio GET che restituisca un solo risultato, sia di tipo entità che primitivo, o che richieda più di un parametro di input.You cannot use CreateQuery to call a GET service operation that returns a single result, of either entity or primitive type, or that requires more than one input parameter. È necessario chiamare invece il metodo Execute.You must instead call the Execute method.

  • Si consiglia di creare un metodo di estensione nella classe parziale DataServiceContext fortemente tipizzata, generato tramite gli strumenti, che usi il metodo CreateQuery o Execute per chiamare un'operazione di servizio.Consider creating an extension method on the strongly-typed DataServiceContext partial class, which is generated by the tools, that uses either the CreateQuery or the Execute method to call a service operation. In questo modo è possibile chiamare operazioni di servizio direttamente dal contesto.This enables you to call service operations directly from the context. Per ulteriori informazioni, vedere il post di blog operazioni del servizio e il Client di WCF Data Services.For more information, see the blog post Service Operations and the WCF Data Services Client.

  • Quando si usa CreateQuery per chiamare un'operazione di servizio, nella libreria client vengono usati automaticamente caratteri di escape forniti al metodo AddQueryOption eseguendo la codifica percentuale di caratteri riservati, ad esempio la e commerciale (&), ed eseguendo l'escape delle virgolette singole nelle stringhe.When you use CreateQuery to call a service operation, the client library automatically escapes characters supplied to the AddQueryOption by performing percent-encoding of reserved characters, such as ampersand (&), and escaping of single-quotes in strings. Tuttavia, quando si chiama uno del Execute metodi per chiamare un'operazione di servizio, è necessario ricordarsi di eseguire i caratteri di escape di tutti i valori stringa forniti dall'utente.However, when you call one of the Execute methods to call a service operation, you must remember to perform this escaping of any user-supplied string values. Per le virgolette singole negli URI vengono usati come caratteri di escape coppie di virgolette singole.Single-quotes in URIs are escaped as pairs of single-quotes.

Esempi di chiamata di operazioni di servizioExamples of Calling Service Operations

Questa sezione contiene gli esempi seguenti relativi alle modalità di chiamata delle operazioni di servizio tramite la libreria client WCF Data ServicesWCF Data Services:This section contains the following examples of how to call service operations by using the WCF Data ServicesWCF Data Services client library:

Chiamata di Execute<T > per restituire una raccolta di entitàCalling Execute<T> to Return a Collection of Entities

Nell'esempio seguente viene chiamata un'operazione di servizio denominata GetOrdersByCity che accetta un parametro stringa city e restituisce un oggetto IQueryable<T>:The following example calls a service operation named GetOrdersByCity, which takes a string parameter of city and returns an IQueryable<T>:

// Define the service operation query parameter.
string city = "London";

// Define the query URI to access the service operation with specific 
// query options relative to the service URI.
string queryString = string.Format("GetOrdersByCity?city='{0}'", city)
    + "&$orderby=ShippedDate desc"
    + "&$expand=Order_Details";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

try
{
    // Execute the service operation that returns all orders for the specified city.
    var results = context.Execute<Order>(new Uri(queryString, UriKind.Relative));

    // Write out order information.
    foreach (Order o in results)
    {
        Console.WriteLine(string.Format("Order ID: {0}", o.OrderID));

        foreach (Order_Detail item in o.Order_Details)
        {
            Console.WriteLine(String.Format("\tItem: {0}, quantity: {1}",
                item.ProductID, item.Quantity));
        }
    }
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}
' Define the service operation query parameter.
Dim city As String = "London"

' Define the query URI to access the service operation with specific 
' query options relative to the service URI.
Dim queryString As String = String.Format("GetOrdersByCity?city='{0}'", city) _
                            & "&$orderby=ShippedDate desc" _
                            & "&$expand=Order_Details"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

Try

    ' Execute the service operation that returns all orders for the specified city.
    Dim results = context.Execute(Of Order)(New Uri(queryString, UriKind.Relative))

    ' Write out order information.
    For Each o As Order In results
        Console.WriteLine(String.Format("Order ID: {0}", o.OrderID))
        For Each item As Order_Detail In o.Order_Details
            Console.WriteLine(String.Format(vbTab & "Item: {0}, quantity: {1}", _
                item.ProductID, item.Quantity))
        Next
    Next
Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response

    Console.WriteLine(response.Error.Message)
End Try

In questo esempio l'operazione di servizio restituisce una raccolta di oggetti Order con oggetti Order_Detail correlati.In this example, the service operation returns a collection of Order objects with related Order_Detail objects.

Utilizzo di CreateQuery<T > per restituire una raccolta di entitàUsing CreateQuery<T> to Return a Collection of Entities

Nell'esempio seguente viene usato CreateQuery per restituire un oggetto DataServiceQuery<TElement> usato per chiamare la stessa operazione di servizio GetOrdersByCity:The following example uses the CreateQuery to return a DataServiceQuery<TElement> that is used to call the same GetOrdersByCity service operation:

// Define the service operation query parameter.
string city = "London";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

// Use the CreateQuery method to create a query that accessess
// the service operation passing a single parameter.       
var query = context.CreateQuery<Order>("GetOrdersByCity")
    .AddQueryOption("city", string.Format("'{0}'", city))
    .Expand("Order_Details");

try
{
    // The query is executed during enumeration.
    foreach (Order o in query)
    {
        Console.WriteLine(string.Format("Order ID: {0}", o.OrderID));

        foreach (Order_Detail item in o.Order_Details)
        {
            Console.WriteLine(String.Format("\tItem: {0}, quantity: {1}",
                item.ProductID, item.Quantity));
        }
    }
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}
' Define the service operation query parameter.
Dim city As String = "London"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

' Use the CreateQuery method to create a query that accessess
' the service operation passing a single parameter.       
Dim query = context.CreateQuery(Of Order)("GetOrdersByCity") _
        .AddQueryOption("city", String.Format("'{0}'", city)).Expand("Order_Details")

Try
    ' The query is executed during enumeration.
    For Each o As Order In query
        Console.WriteLine(String.Format("Order ID: {0}", o.OrderID))
        For Each item As Order_Detail In o.Order_Details
            Console.WriteLine(String.Format(vbTab & "Item: {0}, quantity: {1}", _
                item.ProductID, item.Quantity))
        Next
    Next
Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response
    Console.WriteLine(response.Error.Message)
End Try

In questo esempio il metodo AddQueryOption viene usato per aggiungere il parametro alla query, mentre il metodo Expand viene usato per includere oggetti Order_Details correlati nei risultati.In this example, the AddQueryOption method is used to add the parameter to the query, and the Expand method is used to include related Order_Details objects in the results.

Chiamata di Execute<T > per restituire una singola entitàCalling Execute<T> to Return a Single Entity

Nell'esempio seguente viene chiamata un'operazione di servizio denominata GetNewestOrder che restituisce solo un'entità Order singola:The following example calls a service operation named GetNewestOrder that returns only a single Order entity:

// Define the query URI to access the service operation, 
// relative to the service URI.
string queryString = "GetNewestOrder";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

try
{
    // Execute a service operation that returns only the newest single order.
    Order order
        = (context.Execute<Order>(new Uri(queryString, UriKind.Relative)))
        .FirstOrDefault();

    // Write out order information.
    Console.WriteLine(string.Format("Order ID: {0}", order.OrderID));
    Console.WriteLine(string.Format("Order date: {0}", order.OrderDate));
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}
' Define the query URI to access the service operation, 
' relative to the service URI.
Dim queryString As String = "GetNewestOrder"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

Try
    ' Execute a service operation that returns only the newest single order.
    Dim o As Order = _
        context.Execute(Of Order)( _
            New Uri(queryString, UriKind.Relative)).FirstOrDefault()

    ' Write out order information.
    Console.WriteLine(String.Format("Order ID: {0}", o.OrderID))
    Console.WriteLine(String.Format("Order date: {0}", o.OrderDate))
Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response

    Console.WriteLine(response.Error.Message)
End Try

In questo esempio il metodo FirstOrDefault viene usato per richiedere solo un'entità Order singola durante l'esecuzione.In this example, the FirstOrDefault method is used to request only a single Order entity on execution.

Chiamata di Execute<T > per restituire una raccolta di valori primitiviCalling Execute<T> to Return a Collection of Primitive Values

Nell'esempio seguente viene chiamata un'operazione di servizio che restituisce una raccolta di valori stringa:The following example calls a service operation that returns a collection of string values:

// Define the query URI to access the service operation, 
// relative to the service URI.
string queryString = "GetCustomerNames";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

try
{
    // Execute a service operation that returns only the newest single order.
    IEnumerable<string> customerNames
        = context.Execute<string>(new Uri(queryString, UriKind.Relative));
    
    foreach (string name in customerNames)
    {
        // Write out order information.
        Console.WriteLine(name);
    }
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}

Chiamata di Execute<T > per restituire un valore primitivo singoloCalling Execute<T> to Return a Single Primitive Value

Nell'esempio seguente viene chiamata un'operazione di servizio che restituisce un valore stringa singolo:The following example calls a service operation that returns a single string value:

// Define the query URI to access the service operation, 
// relative to the service URI.
string queryString = "CountOpenOrders";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

try
{
    // Execute a service operation that returns the integer 
    // count of open orders.
    int numOrders
        = (context.Execute<int>(new Uri(queryString, UriKind.Relative)))
        .FirstOrDefault();

    // Write out the number of open orders.
    Console.WriteLine(string.Format("Open orders as of {0}: {1}",
        DateTime.Today.Date, numOrders));
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}
' Define the query URI to access the service operation, 
' relative to the service URI.
Dim queryString As String = "CountOpenOrders"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

Try
    ' Execute a service operation that returns the integer 
    ' count of open orders.
    Dim numOrders As Integer = context.Execute(Of Integer)( _
        New Uri(queryString, UriKind.Relative)).FirstOrDefault()

    ' Write out the number of open orders.
    Console.WriteLine(String.Format("Open orders as of {0}: {1}",
        DateTime.Today.Date, numOrders))
Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response

    Console.WriteLine(response.Error.Message)
End Try

In questo esempio il metodo FirstOrDefault viene usato per richiedere solo un valore Integer singolo durante l'esecuzione.Again in this example, the FirstOrDefault method is used to request only a single integer value on execution.

Chiamata di un'operazione di servizio che non restituisce datiCalling a Service Operation that Returns No Data

Nell'esempio seguente viene chiamata un'operazione di servizio che non restituisce dati:The following example calls a service operation that returns no data:

// Define the query URI to access the service operation, 
// relative to the service URI.
string queryString = "ReturnsNoData";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

try
{
    // Execute a service operation that returns void.
    context.Execute<string>(new Uri(queryString, UriKind.Relative));
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

    Console.WriteLine(response.Error.Message);
}
' Define the query URI to access the service operation, 
' relative to the service URI.
Dim queryString As String = "ReturnsNoData"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

Try
    ' Execute a service operation that returns void.
    context.Execute(Of String)( _
        New Uri(queryString, UriKind.Relative))
Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response

    Console.WriteLine(response.Error.Message)
End Try

Poiché non vengono restituiti dati, il valore dell'esecuzione non viene assegnato.Because not data is returned, the value of the execution is not assigned. L'unica indicazione relativa all'esito positivo della richiesta è la mancata generazione di un'eccezione DataServiceQueryException.The only indication that the request has succeeded is that no DataServiceQueryException is raised.

Chiamata di un'operazione di servizio in modo asincronoCalling a Service Operation Asynchronously

Nell'esempio seguente viene chiamata un'operazione di servizio in modo asincrono tramite BeginExecute e EndExecute:The following example calls a service operation asynchronously by calling BeginExecute and EndExecute:

// Define the service operation query parameter.
string city = "London";

// Define the query URI to access the service operation with specific 
// query options relative to the service URI.
string queryString = string.Format("GetOrdersByCity?city='{0}'", city)
    + "&$orderby=ShippedDate desc"
    + "&$expand=Order_Details";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

// Execute the service operation that returns 
// all orders for the specified city.
var results = context.BeginExecute<Order>(
    new Uri(queryString, UriKind.Relative),
    OnAsyncExecutionComplete, context);
' Define the service operation query parameter.
Dim city As String = "London"

' Define the query URI to access the service operation with specific 
' query options relative to the service URI.
Dim queryString As String = String.Format("GetOrdersByCity?city='{0}'", city) _
        & "&$orderby=ShippedDate desc" _
        & "&$expand=Order_Details"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

' Define the delegate to callback into the process
Dim callback As AsyncCallback = AddressOf OnAsyncExecutionComplete

' Execute the service operation that returns 
' all orders for the specified city.
Dim results = context.BeginExecute(Of Order)( _
    New Uri(queryString, UriKind.Relative), _
    callback, context)
private static void OnAsyncExecutionComplete(IAsyncResult result)
{
    // Get the context back from the stored state.
    var context = result.AsyncState as NorthwindEntities;
    
    try
    {
        // Complete the exection and write out the results.
        foreach (Order o in context.EndExecute<Order>(result))
        {
            Console.WriteLine(string.Format("Order ID: {0}", o.OrderID));

            foreach (Order_Detail item in o.Order_Details)
            {
                Console.WriteLine(String.Format("\tItem: {0}, quantity: {1}",
                    item.ProductID, item.Quantity));
            }
        }
    }
    catch (DataServiceQueryException ex)
    {
        QueryOperationResponse response = ex.Response;

        Console.WriteLine(response.Error.Message);
    }
}
Private Shared Sub OnAsyncExecutionComplete(ByVal result As IAsyncResult)

    ' Get the context back from the stored state.
    Dim context = TryCast(result.AsyncState, NorthwindEntities)

    Try
        ' Complete the exection and write out the results.
        For Each o As Order In context.EndExecute(Of Order)(result)
            Console.WriteLine(String.Format("Order ID: {0}", o.OrderID))

            For Each item As Order_Detail In o.Order_Details
                Console.WriteLine(String.Format(vbTab & "Item: {0}, quantity: {1}", _
                    item.ProductID, item.Quantity))
            Next
        Next
    Catch ex As DataServiceQueryException
        Dim response As QueryOperationResponse = ex.Response
        Console.WriteLine(response.Error.Message)
    End Try
End Sub

Poiché non vengono restituiti dati, il valore restituito dell'esecuzione non viene assegnato.Because no data is returned, the value returned by the execution is not assigned. L'unica indicazione relativa all'esito positivo della richiesta è la mancata generazione di un'eccezione DataServiceQueryException.The only indication that the request has succeeded is that no DataServiceQueryException is raised.

Nell'esempio seguente viene chiamata la stessa operazione di servizio in modo asincrono tramite CreateQuery:The following example calls the same service operation asynchronously by using CreateQuery:

// Define the service operation query parameter.
string city = "London";

// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri2);

// Use the CreateQuery method to create a query that accessess
// the service operation passing a single parameter.       
var query = context.CreateQuery<Order>("GetOrdersByCity")
    .AddQueryOption("city", string.Format("'{0}'", city))
    .Expand("Order_Details");

// Execute the service operation that returns 
// all orders for the specified city.
var results = 
    query.BeginExecute(OnAsyncQueryExecutionComplete, query);
' Define the service operation query parameter.
Dim city As String = "London"

' Create the DataServiceContext using the service URI.
Dim context As NorthwindEntities = New NorthwindEntities(svcUri2)

' Use the CreateQuery method to create a query that accessess
' the service operation passing a single parameter.       
Dim query = context.CreateQuery(Of Order)("GetOrdersByCity") _
            .AddQueryOption("city", String.Format("'{0}'", city)) _
            .Expand("Order_Details")

' Define the delegate to callback into the process
Dim callback As AsyncCallback = AddressOf OnAsyncQueryExecutionComplete

' Execute the service operation that returns 
' all orders for the specified city.
Dim results = _
    query.BeginExecute(callback, query)
private static void OnAsyncQueryExecutionComplete(IAsyncResult result)
{
    // Get the query back from the stored state.
    var query = result.AsyncState as DataServiceQuery<Order>;
    
    try
    {
        // Complete the exection and write out the results.
        foreach (Order o in query.EndExecute(result))
        {
            Console.WriteLine(string.Format("Order ID: {0}", o.OrderID));

            foreach (Order_Detail item in o.Order_Details)
            {
                Console.WriteLine(String.Format("\tItem: {0}, quantity: {1}",
                    item.ProductID, item.Quantity));
            }
        }
    }
    catch (DataServiceQueryException ex)
    {
        QueryOperationResponse response = ex.Response;

        Console.WriteLine(response.Error.Message);
    }
}
Private Shared Sub OnAsyncQueryExecutionComplete(ByVal result As IAsyncResult)
    ' Get the query back from the stored state.
    Dim query = TryCast(result.AsyncState, DataServiceQuery(Of Order))

    Try
        ' Complete the exection and write out the results.
        For Each o As Order In query.EndExecute(result)

            Console.WriteLine(String.Format("Order ID: {0}", o.OrderID))

            For Each item As Order_Detail In o.Order_Details
                Console.WriteLine(String.Format(vbTab & "Item: {0}, quantity: {1}", _
                    item.ProductID, item.Quantity))
            Next
        Next
    Catch ex As DataServiceQueryException
        Dim response As QueryOperationResponse = ex.Response

        Console.WriteLine(response.Error.Message)
    End Try
End Sub

Vedere ancheSee Also

Libreria client WCF Data ServicesWCF Data Services Client Library