Querying with WCF Data Services Client Library

Description and code samples
Table of Contents
Summary

When using the Client library the query is built through the DataServiceQuery::AddQueryOption method:
when a query option is added a new DataServiceQuery object with the selected query option applied is returned -
the query option is appended to the resultant URI using the ?$name=value&$name2=value2… sintax.

Description

The WCF Data Services supports the following system query options defined by the OData protocol:

QUERY OPTION DESCRIPTION
orderby Defines a default sort order for entities in the returned feed
top Specifies the number of entities to include in the returned feed
skip Specifies the number of entities to skip before starting to return entities in the feed
filter Specifies the filter of entities to apply before return entities in the feed
expand Specifies which related entities are returned by the query. Related entities are included as either a feed or an entry inline with the entity returned by the query
select Specifies a projection that defines the properties of the entity are returned in the projection
inlinecount Requests that a count of the number of entities returned in the feed be included with the feed
format Specifies the media type to be used in the response.
Supported formats are:

  • Atom, media type: Application/atom+xml 
  • Xml, media type: Application/xml 
  • Json, media type: Application/json. In order to support the JSON format the service class must be decorated with the JSONPSupportBehavior attribute. Refer to the this article to obtain the required extension code.

The expression language that is used in $filter operators supports references to properties and literals:

Operator Description Example
Logical Operators
Eq Equal /Suppliers?$filter=Address/City eq ‘Redmond’
Ne Not equal /Suppliers?$filter=Address/City ne ‘London’
Gt Greater than /Products?$filter=Price gt 20
Ge Greater than or equal /Products?$filter=Price ge 10
Lt Less than /Products?$filter=Price lt 20
Le Less than or equal /Products?$filter=Price le 100
And Logical and /Products?$filter=Price le 200 and Price gt 3.5
Or Logical or /Products?$filter=Price le 3.5 or Price gt 200
Not Logical negation /Products?$filter=not endswith(Description,’milk’)
Arithmetic Operators
Add Addition /Products?$filter=Price add 5 gt 10
Sub Subtraction /Products?$filter=Price sub 5 gt 10
Mul Multiplication /Products?$filter=Price mul 2 gt 2000
Div Division /Products?$filter=Price div 2 gt 4
Mod Modulo /Products?$filter=Price mod 2 eq 0
Grouping Operators
( ) Precedence grouping /Products?$filter=(Price sub 5) gt 10

A set of functions are defined for use with the filter query string operator:

Function Example
String Functions
bool substringof(string po, string p1) http://localhost/Training/WcfDataService1.svc/Customers?$filter=substringof(‘Alfreds’, CompanyName) eq true
bool endswith(string p0, string p1) http://localhost/Training/WcfDataService1.svc/Customers?$filter=endswith(CompanyName, ‘Futterkiste’) eq true
bool startswith(string p0, string p1) http://localhost/Training/WcfDataService1.svc/Customers?$filter=startswith(CompanyName, ‘Alfr’) eq true
int length(string p0) http://localhost/Training/WcfDataService1.svc/Customers?$filter=length(CompanyName) eq 19
int indexof(string p0, string p1) http://localhost/Training/WcfDataService1.svc/Customers?$filter=indexof(CompanyName, ‘lfreds’) eq 1
string replace(string p0, string find, string replace) http://localhost/Training/WcfDataService1.svc/Customers?$filter=replace(CompanyName, ‘ ‘, ”) eq ‘AlfredsFutterkiste’
string substring(string p0, int pos) http://localhost/Training/WcfDataService1.svc/Customers?$filter=substring(CompanyName, 1) eq ‘lfreds Futterkiste’
string substring(string p0, int pos, int length) http://localhost/Training/WcfDataService1.svc/Customers?$filter=substring(CompanyName, 1, 2) eq ‘lf’
string tolower(string p0) http://localhost/Training/WcfDataService1.svc/Customers?$filter=tolower(CompanyName) eq ‘alfreds futterkiste’
string toupper(string p0) http://localhost/Training/WcfDataService1.svc/Customers?$filter=toupper(CompanyName) eq ‘ALFREDS FUTTERKISTE’
string trim(string p0) http://localhost/Training/WcfDataService1.svc/Customers?$filter=trim(CompanyName) eq ‘Alfreds Futterkiste’
string concat(string p0, string p1) http://localhost/Training/WcfDataService1.svc/Customers?$filter=concat(concat(City, ‘, ‘), Country) eq ‘Berlin, Germany’
Date Functions
int day(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=day(BirthDate) eq 8
int hour(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=hour(BirthDate) eq 0
int minute(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=minute(BirthDate) eq 0
int month(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=month(BirthDate) eq 12
int second(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=second(BirthDate) eq 0
int year(DateTime p0) http://localhost/Training/WcfDataService1.svc/Employees?$filter=year(BirthDate) eq 1948
Math Functions
double round(double p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=round(Freight) eq 32
decimal round(decimal p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=round(Freight) eq 32
double floor(double p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=filter=round(Freight) eq 32
decimal floor(decimal p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=floor(Freight) eq 32
double ceiling(double p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=ceiling(Freight) eq 33
decimal ceiling(decimal p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=floor(Freight) eq 33
Type Functions
bool IsOf(type p0) http://localhost/Training/WcfDataService1.svc/Orders?$filter=isof(‘NorthwindModel.Order’)
bool IsOf(expression p0, type p1) http://localhost/Training/WcfDataService1.svc/Orders?$filter=isof(ShipCountry, ‘Edm.String’)
Note

The client library automatically escapes characters supplied to the AddQueryOption
by performing percent-encoding of reserved characters (e.g. &), and escaping of single-quotes in strings.

All the samples included in this article were retrieved from URI Conventions description

Operations
Create the DataServiceContext using the service URI
How to do it
TrainingEntities context = new TraningEntities(new Uri("http://localhost/TrainingService1/"));
Queries with no options applied
How to do it
// Define a new query for Customers wihout any option applied
DataServiceQuery<Customer> query = context.Customers;

Translated URI:

http://localhost:12345/TrainingService.svc/Customers()
Queries with projections options

Projection provides a mechanism to reduce the amount of data returned by a query by specifying that only certain properties of an entity are returned in the response

How to do it
DataServiceQuery<Order> query = context.Orders.AddQueryOption("$filter", "CustomerID eq jseixas").AddQueryOption("$select", "CustomerID,Address,City,Region,PostalCode,Country");

Translated URI:

http://localhost:12345/TrainingService.svc/Customers()?$filter=CustomerID eq 'jseixas'&$select=CustomerID,Address,City,Region,PostalCode,Country
Queries with deferred selection options
How to do it
DataServiceQuery<Order> query = context.Orders.AddQueryOption("$filter", "CustomerID eq jseixas").AddQueryOption("$expand","Order_Details");

Translated URI:

http://localhost:12345/TrainingService.svc/Orders()?$filter=CustomerID eq 'jseixas'&$expand=Order_Details.