Abfragen des Datendiensts (WCF Data Services)

Die WCF Data Services -Clientbibliothek ermöglicht es Ihnen, Abfragen für einen Datendienst mit vertrauten .NET Framework-Programmierschemas auszuführen, u. a. mithilfe von LINQ (Language Integrated Query). Die Clientbibliothek übersetzt eine Abfrage, die auf dem Client als Instanz der DataServiceQuery-Klasse definiert wird, in eine HTTP GET-Anforderungsnachricht. Die Bibliothek empfängt die Antwortnachricht und übersetzt sie in Instanzen von Clientdatendienstklassen. Diese Klassen werden vom DataServiceContext verfolgt, zu dem DataServiceQuery gehört.

Datendienstabfragen

Die generische Klasse DataServiceQuery stellt eine Abfrage dar, die eine Auflistung von null oder mehr Entitätstypinstanzen zurückgibt. Eine Datendienstabfrage ist immer einem vorhandenen Datendienstkontext zugeordnet. Dieser Kontext verwaltet den Dienst-URI und die Metadateninformationen, die zum Erstellen und Ausführen der Abfrage erforderlich sind.

Wenn Sie das Dialogfeld Dienstverweis hinzufügen verwenden, um einer .NET Framework-basierten Clientanwendung einen Datendienst hinzuzufügen, wird eine Entitätscontainerklasse erstellt, die von der DataServiceContext-Klasse erbt. Diese Klasse enthält Eigenschaften, die typisierte DataServiceQuery-Instanzen zurückgeben. Es ist eine Eigenschaft für jede Entitätenmenge vorhanden, die der Datendienst verfügbar macht. Diese Eigenschaften erleichtern es, eine Instanz eines typisierten DataServiceQuery-Objekts zu erstellen.

In den folgenden Szenarien wird eine Abfrage ausgeführt:

  • Wenn Ergebnisse implizit aufgezählt werden, z. B.:

    • Wenn eine Eigenschaft für den DataServiceContext, der eine Entitätenmenge darstellt, aufgezählt wird, z. B. in einer foreach-Schleife (C#) oder einer For Each-Schleife (Visual Basic).

    • Wenn die Abfrage einer List-Auflistung zugewiesen wird.

  • Wenn die Execute-Methode oder die BeginExecute-Methode explizit aufgerufen wird.

  • Wenn ein LINQ-Abfrageausführungsoperator wie First oder Single aufgerufen wird.

Wenn die folgende Abfrage ausgeführt wird, gibt sie alle Customers-Entitäten im Northwind-Datendienst zurück:

' 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;

Weitere Informationen finden Sie unter Gewusst wie: Ausführen von Datendienstabfragen (WCF Data Services).

Der WCF Data Services -Client unterstützt Abfragen für spät gebundene Objekte, z. B. bei der Verwendung des dynamischen Typs in C#. Aus Leistungsgründen sollten für den Datendienst jedoch immer stark typisierte Abfragen verfasst werden. Der Tuple-Typ und dynamische Objekte werden nicht vom Client unterstützt.

LINQ-Abfragen

Da die DataServiceQuery-Klasse die von LINQ definierte IQueryable-Schnittstelle implementiert, kann die WCF Data Services -Clientbibliothek LINQ-Abfragen für Entitätenmengendaten in einen URI umwandeln, der einen für eine Datendienstressource ausgewerteten Abfrageausdruck darstellt. Das folgende Beispiel ist eine LINQ-Abfrage, die der vorherigen DataServiceQuery-Abfrage entspricht, die Orders mit Frachtkosten von mehr als $30 zurückgibt und die Ergebnisse nach den Frachtkosten sortiert:

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;

Diese LINQ-Abfrage wird in den folgenden Abfrage-URI übersetzt, der für den auf Northwind basierenden Schnellstart-Datendienst ausgeführt wird:

https://localhost:12345/Northwind.svc/Orders?Orderby=ShippedDate&?filter=Freight gt 30
Dd673933.note(de-de,VS.100).gifHinweis:
Die Gruppe von Abfragen, die in der LINQ-Syntax ausgedrückt werden kann, ist umfangreicher als bei der von Datendiensten verwendeten REST-basierten (Representational State Transfer) URI-Syntax. Wenn die Abfrage keinem URI im Zieldatendienst zugeordnet werden kann, wird eine Ausnahme vom Typ NotSupportedException ausgelöst.

Weitere Informationen finden Sie unter Überlegungen zu LINQ (WCF Data Services).

Hinzufügen von Abfrageoptionen

Datendienstabfragen unterstützen alle Abfrageoptionen, die in WCF Data Services verfügbar sind. Sie rufen die AddQueryOption-Methode auf, um Abfrageoptionen an eine DataServiceQuery-Instanz anzufügen. AddQueryOption gibt eine neue DataServiceQuery-Instanz zurück, die der ursprünglichen Abfrage entspricht, aber die neuen Abfrageoptionen enthält. Wenn die folgende Abfrage ausgeführt wird, gibt sie Orders-Objekte zurück, die nach dem Freight-Wert gefiltert und in absteigender Reihenfolge nach dem Wert von OrderID sortiert werden:

' 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");

Sie können die $orderby-Abfrageoption verwenden, um eine Abfrage auf der Grundlage einer einzelnen Eigenschaft sowohl zu sortieren als auch zu filtern, wie im folgenden Beispiel, in dem die zurückgegebenen Orders-Objekte anhand des Werts der Freight-Eigenschaft gefiltert und sortiert werden:

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

Sie können die AddQueryOption-Methode aufrufen, um nacheinander komplexe Abfrageausdrücke zu erstellen. Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen von Abfrageoptionen zu einer Datendienstabfrage (WCF Data Services).

Abfrageoptionen sind eine weitere Möglichkeit, die syntaktischen Komponenten einer LINQ-Abfrage auszudrücken. Weitere Informationen finden Sie unter Überlegungen zu LINQ (WCF Data Services).

Dd673933.note(de-de,VS.100).gifHinweis:
Die $select-Abfrageoption kann einem Abfrage-URI nicht mit der AddQueryOption-Methode hinzugefügt werden. Es wird empfohlen, die Select-LINQ-Methode zu verwenden, damit der Client die $select-Abfrageoption im Anforderungs-URI generiert.

Clientausführung und Serverausführung

Der Client führt eine Abfrage in zwei Teilen aus. Nach Möglichkeit werden Ausdrücke in einer Abfrage zuerst auf dem Client ausgewertet, und anschließend wird eine URI-basierte Abfrage generiert und zur Auswertung anhand der Daten im Dienst an den Datendienst gesendet. Betrachten Sie die folgende LINQ-Abfrage:

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;

In diesem Beispiel wird der Ausdruck (basePrice – (basePrice * discount)) auf dem Client ausgewertet. Der tatsächliche Abfrage-URI https://localhost:12345/northwind.svc/Products()?$filter=(UnitPrice gt 90.00M) and substringof('bike',ProductName), der an den Datendienst gesendet wird, enthält daher den bereits berechneten Dezimalwert 90 in der Filterklausel. Die anderen Teile des Filterausdrucks, einschließlich des untergeordneten Zeichenfolgenausdrucks, werden vom Datendienst ausgewertet. Auf dem Client ausgewertete Ausdrücke entsprechen der CLR-Semantik (Common Language Runtime), während an den Datendienst gesendete Ausdrücke auf der Datendienstimplementierung des OData -Protokolls basieren. Diese getrennte Auswertung kann in bestimmten Szenarien zu unerwarteten Ergebnissen führen, z. B. wenn sowohl der Client als auch der Dienst zeitbasierte Auswertungen in unterschiedlichen Zeitzonen ausführen.

Abfrageantworten

Wenn die Abfrage DataServiceQuery ausgeführt wird, gibt sie eine IEnumerable vom angeforderten Entitätstyp zurück. Dieses Abfrageergebnis kann, wie im folgenden Beispiel, in ein QueryOperationResponse-Objekt umgewandelt werden:

' 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>;

Die Entitätstypinstanzen, die Entitäten im Datendienst darstellen, werden von einem Prozess mit dem Namen Objektmaterialisierung auf dem Client erstellt. Weitere Informationen finden Sie unter Objektmaterialisierung (WCF Data Services). Das QueryOperationResponse-Objekt implementiert IEnumerable, um Zugriff auf die Ergebnisse der Abfrage zu bieten.

Der QueryOperationResponse verfügt auch über die folgenden Member, die es Ihnen ermöglichen, auf weitere Informationen zu einem Abfrageergebnis zuzugreifen:

  • Error- ruft einen vom Vorgang ausgelösten Fehler ab, sofern ein Fehler aufgetreten sind.

  • Headers- enthält die Sammlung der mit der Abfrageantwort verbundenen HTTP-Antwortheader.

  • Query - ruft die ursprüngliche DataServiceQuery-Abfrage ab, welche die QueryOperationResponse-Antwort erzeugte.

  • StatusCode - ruft den HTTP-Antwortcode für die Abfrageantwort ab.

  • TotalCount- ruft die Gesamtzahl der Entitäten ab, die in der Entitätenmenge enthalten war, wenn die IncludeTotalCount-Methode für DataServiceQuery aufgerufen wurde.

  • GetContinuation- gibt ein DataServiceQueryContinuation-Objekt zurück, das den URI der nächsten Seite mit Ergebnissen enthält.

Standardmäßig gibt WCF Data Services nur Daten zurück, die explizit über den Abfrage-URI ausgewählt werden. Dies gibt Ihnen die Möglichkeit, bei Bedarf weitere Daten explizit vom Datendienst zu laden. Jedes Mal, wenn Daten explizit aus dem Datendienst geladen werden, wird eine Anforderung an den Datendienst gesendet. Zu den Daten, die explizit geladen werden können, gehören verknüpfte Entitäten, ausgelagerte Antwortdaten und Binärdatenströme.

Dd673933.note(de-de,VS.100).gifHinweis:
Da ein Datendienst möglicherweise eine ausgelagerte Antwort zurückgibt, empfiehlt es sich, dass die Anwendung das Programmiermuster zur Behandlung ausgelagerter Datendienstantworten verwendet. Weitere Informationen finden Sie unter Laden von verzögertem Inhalt (WCF Data Services).

Die von einer Abfrage zurückgegebene Datenmenge kann auch durch die Angabe reduziert werden, dass nur bestimmte Eigenschaften einer Entität in der Antwort zurückgegeben werden. Weitere Informationen finden Sie unter Abfrageprojektionen (WCF Data Services).

Abrufen der Gesamtanzahl der in der Menge enthaltenen Entitäten

In einigen Szenarien ist es hilfreich zu wissen, wie viele Entitäten in einer Entitätenmenge insgesamt enthalten sind, statt nur die von der Abfrage zurückgegebene Anzahl zu kennen. Rufen Sie die IncludeTotalCount-Methode für DataServiceQuery auf, um anzufordern, dass die Gesamtanzahl von Entitäten dieser Entitätenmenge in das Abfrageergebnis aufgenommen wird. In diesem Fall gibt die TotalCount-Eigenschaft der zurückgegebenen QueryOperationResponse-Instanz die Gesamtzahl der in der Menge enthaltenen Entitäten zurück.

Sie können auch nur die Gesamtanzahl der Entitäten in der Menge als Int32-Wert oder Int64-Wert abrufen, indem Sie Count-Methode bzw. die LongCount-Methode aufrufen. Wenn diese Methoden aufgerufen werden, wird kein QueryOperationResponse-Objekt zurückgegeben. Es wird nur die Anzahl zurückgegeben. Weitere Informationen finden Sie unter Gewusst wie: Bestimmen der Anzahl von Entitäten, die von einer Abfrage zurückgegeben werden (WCF Data Services).

In diesem Abschnitt

Abfrageprojektionen (WCF Data Services)

Objektmaterialisierung (WCF Data Services)

Überlegungen zu LINQ (WCF Data Services)

Gewusst wie: Ausführen von Datendienstabfragen (WCF Data Services)

Gewusst wie: Hinzufügen von Abfrageoptionen zu einer Datendienstabfrage (WCF Data Services)

Gewusst wie: Bestimmen der Anzahl von Entitäten, die von einer Abfrage zurückgegeben werden (WCF Data Services)

Vorgehensweise: Angeben von Clientanmeldeinformationen für eine Datendienstanforderung (WCF Data Services)

Vorgehensweise: Festlegen von Headern in der Clientanforderung (WCF Data Services)

Gewusst wie: Projizieren von Abfrageergebnissen (WCF Data Services)

Siehe auch

Weitere Ressourcen

WCF Data Services-Clientbibliothek