共用方式為


呼叫服務作業和動作 (WCF Data Services)

Open Data Protocol (OData) 會針對資料服務定義服務作業和服務動作。 就像其他資料服務資源,服務作業和服務動作會使用 URI 來定址。 服務作業和動作都可以傳回實體類型集合、單一實體類型執行個體、基本類型 (例如整數和字串) 以及 null (Visual Basic 中為 Nothing)。 與服務作業不同的是,服務動作可以繫結至資料模型資源而且必須使用 HTTP POST 要求來呼叫,因為服務動作對系統有副作用。 如需詳細資訊,請參閱服務作業 (WCF Data Services)使用 OData 動作實作伺服器端行為

服務作業和服務動作都會在實作 OData 之資料服務所傳回的中繼資料中公開。 在中繼資料中,兩者都會表示為 FunctionImport 元素。 產生強型別 DataServiceContext 時,[加入服務參考] 和 DataSvcUtil.exe 工具會忽略此元素。 因此,您在內容上找不到可用來直接呼叫服務作業的方法。 但是,您仍然可以使用 WCF Data Services 用戶端,透過下列兩種方式呼叫服務作業:

呼叫服務作業和動作的考量

使用 WCF Data Services 用戶端呼叫服務作業時,適用下列考量。

呼叫服務作業的範例

本節包含下列範例,說明如何使用 WCF Data Services 用戶端程式庫呼叫服務作業:

呼叫 Execute<T> 以傳回實體集合

下列範例會呼叫名為 GetOrdersByCity 的服務作業,這項作業接受字串參數 city 並傳回 IQueryable<T>

' 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
// 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);
}

在此範例中,服務作業會傳回 Order 物件集合與相關的 Order_Detail 物件。

使用 CreateQuery<T> 以傳回實體集合

下列範例會使用 CreateQuery<T>(String) 傳回用來呼叫相同 GetOrdersByCity 服務作業的 DataServiceQuery<TElement>

' 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
// 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);
}

在此範例中,AddQueryOption(String, Object) 方法用於將參數加入至查詢中,而 Expand(String) 方法則用於將相關的 Order_Details 物件包含在結果中。

呼叫 Execute<T> 以傳回單一實體

下列範例會呼叫名為 GetNewestOrder 的服務作業,這項作業只傳回單一 Order 實體:

' 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
// 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);
}

此範例會使用 FirstOrDefault<TSource>(IEnumerable<TSource>) 方法,在執行時只要求單一 Order 實體。

呼叫 Execute<T> 以傳回基本值集合

下列範例會呼叫傳回字串值集合的服務作業:

' Define the query URI to access the service operation, 
' relative to the service URI.
Dim queryString As String = "GetCustomerNames"

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

Try

    ' Execute a service operation that returns a collection of customer names.
    Dim customerNames As IEnumerable(Of String) _
        = context.Execute(Of String)(New Uri(queryString, UriKind.Relative))

    For Each name As String In customerNames
        ' Write out customer information.
        Console.WriteLine(name)
    Next

Catch ex As DataServiceQueryException
    Dim response As QueryOperationResponse = ex.Response

    Console.WriteLine(response.Error.Message)
End Try
// 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 a collection of customer names
    IEnumerable<string> customerNames
        = context.Execute<string>(new Uri(queryString, UriKind.Relative));

    foreach (string name in customerNames)
    {
        // Write out customer information.
        Console.WriteLine(name);
    }
}
catch (DataServiceQueryException ex)
{
    QueryOperationResponse response = ex.Response;

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

呼叫 Execute<T> 以傳回單一基本值

下列範例會呼叫傳回單一字串值的服務作業:

' 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
// 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);
}

此範例又一次使用 FirstOrDefault<TSource>(IEnumerable<TSource>) 方法,在執行時只要求單一整數值。

呼叫不傳回任何資料的服務作業

下列範例會呼叫不傳回任何資料的服務作業:

' 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
// 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);
}

由於不傳回資料,因此沒有指派執行的值。 指出要求已成功的唯一表示就是沒有引發 DataServiceQueryException

非同步呼叫服務作業

下列範例會藉由呼叫 BeginExecute<TElement>(Uri, AsyncCallback, Object)EndExecute<TElement>(IAsyncResult),非同步呼叫服務作業:

' 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)
// 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);
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
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);
    }
}

由於不傳回資料,因此沒有指派執行傳回的值。 指出要求已成功的唯一表示就是沒有引發 DataServiceQueryException

下列範例會使用 CreateQuery<T>(String),非同步呼叫相同的服務作業:

' 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)
// 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);
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
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);
    }
}

請參閱

其他資源

資料用戶端 (WCF Data Services)