Share via


查詢資料服務 (WCF Data Services)

WCF Data Services 用戶端程式庫可讓您使用熟悉的 .NET Framework 程式設計模式針對資料服務執行查詢,包括使用 Language Integrated Query (LINQ)。用戶端程式庫會將查詢轉譯為 HTTP GET 要求訊息,該查詢在用戶端上已定義為 DataServiceQuery 類別的執行個體。程式庫會接收回應訊息,並將它轉譯為用戶端資料服務類別的執行個體。這些類別會由 DataServiceQuery 所屬的 DataServiceContext 追蹤。

資料服務查詢

DataServiceQuery 泛型類別表示傳回零個或多個實體型別執行個體之集合的查詢。資料服務查詢永遠屬於現有的資料服務內容。此內容會維持撰寫及執行查詢所需的服務 URI 和中繼資料 (Metadata) 資訊。

當您使用 [加入服務參考] 對話方塊將資料服務加入 .NET Framework 架構的用戶端應用程式時,會建立繼承自 DataServiceContext 類別的實體容器類別。這個類別包含會傳回具型別之 DataServiceQuery 執行個體的屬性。每一個實體集都有一個屬性,並由資料服務公開。這些屬性可以讓具型別之 DataServiceQuery 執行個體的建立作業更為容易。

以下情況下會執行查詢:

  • 結果以隱含方式列舉時,例如:

    • 列舉代表 DataServiceContext 上的屬性及實體集時,例如 foreach (C#) 或 For Each (Visual Basic) 迴圈期間。

    • 查詢已指派至 List 集合時。

  • 明確呼叫 ExecuteBeginExecute 方法時。

  • 當呼叫 LINQ 查詢執行運算子 (如 FirstSingle) 時。

下列查詢在執行時會傳回 Northwind 資料服務中的所有 Customers 實體:

' Define a new query for Customers.
Dim query As DataServiceQuery(Of Customer) = context.Customers
// Define a new query for Customers.
DataServiceQuery<Customer> query = context.Customers;

如需詳細資訊,請參閱 HOW TO:執行資料服務查詢 (WCF Data Services)

WCF Data Services 用戶端支援晚期繫結物件的查詢,例如,當您在 C# 中使用「動態」(Dynamic) 型別時。不過,基於效能因素,您應該一律針對資料服務撰寫強型別的查詢。用戶端不支援 Tuple 型別和動態物件。

LINQ 查詢

因為 DataServiceQuery 類別會實作由 LINQ 定義之 IQueryable 介面,因此 WCF Data Services 用戶端程式庫可以根據實體集資料將 LINQ 查詢轉換為 URI (其代表針對資料服務資源評估之查詢運算式)。下列範例是 LINQ 查詢,其相當於以前的 DataServiceQuery,它會傳回運費成本超過 $30 的 Orders,並依運費成本排序結果:

Dim selectedOrders = From o In context.Orders _
        Where (o.Freight > 30) _
        Order By o.ShippedDate Descending _
        Select o
var selectedOrders = from o in context.Orders
                     where o.Freight > 30
                     orderby o.ShippedDate descending 
                     select o;

此 LINQ 查詢會轉譯為下列查詢 URI,其會針對 Northwind 架構的快速入門資料服務執行:

https://localhost:12345/Northwind.svc/Orders?Orderby=ShippedDate&?filter=Freight gt 30
Dd673933.note(zh-tw,VS.100).gif注意:
可以用 LINQ 語法表示的查詢集合會比在資料服務所使用之具像狀態傳輸 (REST) 架構 URI 語法中啟用的查詢集合更廣泛。當查詢無法對應至目標資料服務中的 URI,就會引發 NotSupportedException

如需詳細資訊,請參閱 LINQ 考量 (WCF Data Services)

加入查詢選項

資料服務查詢支援 WCF Data Services 提供的所有查詢選項。您要呼叫 AddQueryOption 方法,將查詢選項附加至 DataServiceQuery 執行個體。AddQueryOption 會傳回新的 DataServiceQuery 執行個體,此執行個體相當於原始查詢,但已設定新的查詢選項。下列查詢在執行時會傳回 Orders,其係經由 Freight 值進行篩選並依 OrderID 遞減順序排序:

' Define a query for orders with a Freight value greater than 30
' and that is ordered by the ship date, descending.
Dim selectedOrders As DataServiceQuery(Of Order) = context.Orders _
.AddQueryOption("$filter", "Freight gt 30") _
.AddQueryOption("$orderby", "OrderID desc")
// Define a query for orders with a Freight value greater than 30
// and that is ordered by the ship date, descending.
DataServiceQuery<Order> selectedOrders = context.Orders
    .AddQueryOption("$filter", "Freight gt 30")
    .AddQueryOption("$orderby", "OrderID desc");

您可以使用 $orderby 查詢選項根據單一屬性來排序及篩選查詢,如下列範例根據 Freight 屬性的值篩選及排序傳回的 Orders 物件:

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

' Define a query for orders with a Freight value greater than 30
' that also orders the result by the Freight value, descending.
Dim selectedOrders As DataServiceQuery(Of Order) = _
context.Orders.AddQueryOption("$orderby", "Freight gt 30 desc")

Try
    ' Enumerate over the results of the query.
    For Each order As Order In selectedOrders
        Console.WriteLine("Order ID: {0} - Freight: {1}", _
                order.OrderID, order.Freight)
    Next
Catch ex As DataServiceQueryException
    Throw New ApplicationException( _
            "An error occurred during query execution.", ex)
End Try
// Create the DataServiceContext using the service URI.
NorthwindEntities context = new NorthwindEntities(svcUri);

// Define a query for orders with a Freight value greater than 30
// that also orders the result by the Freight value, descending.
DataServiceQuery<Order> selectedOrders = context.Orders
    .AddQueryOption("$orderby", "Freight gt 30 desc");

try
{
    // Enumerate over the results of the query.
    foreach (Order order in selectedOrders)
    {
        Console.WriteLine("Order ID: {0} - Freight: {1}",
            order.OrderID, order.Freight);
    }
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException(
        "An error occurred during query execution.", ex);
}

您可以連續呼叫 AddQueryOption 方法來建構複雜的查詢運算式。如需詳細資訊,請參閱 HOW TO:將查詢選項加入至資料服務查詢 (WCF Data Services)

查詢選項提供您另一種表示 LINQ 查詢語法元件的方式。如需詳細資訊,請參閱 LINQ 考量 (WCF Data Services)

Dd673933.note(zh-tw,VS.100).gif注意:
您無法使用 AddQueryOption 方法,將 $select 查詢選項加入至查詢 URI。建議您使用 LINQ Select 方法,讓用戶端在要求 URI 中產生 $select 查詢選項。

用戶端與伺服器執行的比較

用戶端會以兩個部分執行查詢。如果可能,查詢中的運算式會先在用戶端上進行評估,然後產生 URI 架構的查詢,並將其傳送至資料服務,以便針對服務中的資料進行評估。請考慮下列 LINQ 查詢:

Dim basePrice As Integer = 100
Dim discount As Decimal = Convert.ToDecimal(0.1)

' Define a query that returns products based on a 
' calculation that is determined on the client.
Dim productsQuery = From p In context.Products
                  Where p.UnitPrice >
                  (basePrice - (basePrice * discount)) AndAlso
                  p.ProductName.Contains("bike")
                  Select p
int basePrice = 100;
decimal discount = .10M;

// Define a query that returns products based on a 
// calculation that is determined on the client.
var productsQuery = from p in context.Products
                  where p.UnitPrice >
                  (basePrice - (basePrice * discount)) &&
                  p.ProductName.Contains("bike")
                  select p;

在此範例中,運算式 (basePrice – (basePrice * discount)) 會在用戶端上進行評估。因此,傳送至資料服務的實際查詢 URI https://localhost:12345/northwind.svc/Products()?$filter=(UnitPrice gt 90.00M) and substringof('bike',ProductName) 在 filter 子句中,包含已經計算的十進位值 90。篩選運算式的另一個部分 (包括子字串運算式),則由資料服務評估。在用戶端上評估的運算式會遵循 Common Language Runtime (CLR) 語意,而傳送到資料服務的運算式則會依賴 OData 通訊協定的資料服務實作。您也應該知道這個個別評估的案例可能會造成非預期的結果,例如,當用戶端和服務同時在不同的時區中執行以時間為基礎的評估時。

查詢回應

執行時,DataServiceQuery 會傳回要求之實體類型的 IEnumerable。此查詢結果可以轉型為 QueryOperationResponse 物件,如下列範例:

' Execute the query for all customers and get the response object.
Dim response As QueryOperationResponse(Of Customer) = _
    CType(query.Execute(), QueryOperationResponse(Of Customer))
// Execute the query for all customers and get the response object.
QueryOperationResponse<Customer> response = 
    query.Execute() as QueryOperationResponse<Customer>;

資料服務中代表實體的實體類型執行個體是透過稱為物件具體化的程序,在用戶端上建立的。如需詳細資訊,請參閱物件具體化 (WCF Data Services)QueryOperationResponse 物件會實作 IEnumerable 以提供查詢結果的存取權。

QueryOperationResponse 還有下列成員,可讓您存取有關查詢結果的其他資訊:

根據預設,WCF Data Services 只會傳回查詢 URI 所明確選取的資料。它還提供選項可讓您於必要時,從資料服務明確載入其他資料。每次您從資料服務明確載入資料時,就會傳送一個要求至資料服務。可以明確載入的資料包括相關實體、分頁的回應資料,以及二進位資料流。

Dd673933.note(zh-tw,VS.100).gif注意:
因為資料服務可能傳回分頁的回應,我們建議您的應用程式使用程式設計模式來處理分頁的資料服務回應。如需詳細資訊,請參閱載入延後的內容 (WCF 資料服務)

指定回應中僅傳回特定實體屬性,也可以降低查詢傳回的資料量。如需詳細資訊,請參閱查詢投影 (WCF 資料服務)

取得集合中實體總數的計數

在部分情況下,這麼做有助於得知實體集中的實體總數,且不僅是查詢傳回的數目。在 DataServiceQuery 上呼叫 IncludeTotalCount 方法,以要求集合中的這項實體總計數包含在查詢結果中。在此案例中,傳回之 QueryOperationResponseTotalCount 屬性會傳回集合中的實體總數。

您也可以分別呼叫 CountLongCount 方法,藉此只取得集合中的實體總計數做為 Int32 或做為 Int64 值。呼叫這些方法時,並未傳回 QueryOperationResponse;只會傳回計數值。如需詳細資訊,請參閱 HOW TO:判斷查詢傳回的實體數目 (WCF Data Services)

本章節內容

查詢投影 (WCF 資料服務)

物件具體化 (WCF Data Services)

LINQ 考量 (WCF Data Services)

HOW TO:執行資料服務查詢 (WCF Data Services)

HOW TO:將查詢選項加入至資料服務查詢 (WCF Data Services)

HOW TO:判斷查詢傳回的實體數目 (WCF Data Services)

HOW TO:指定資料服務要求的用戶端認證 (WCF Data Services)

HOW TO:設定用戶端要求中的標頭 (WCF Data Services)

HOW TO:專案查詢結果 (WCF Data Services)

另請參閱

其他資源

WCF Data Services 用戶端程式庫