Series: This post is the sixth part of the Data Services Expressions Series which describes expressions generated by WCF Data Services.

We will be looking into navigations in the next couple of posts. To be able to do that we first have to explain so called key lookups. With a query to a given entity set, the service returns all the entities in that set. We can use filters and such to limit the entities returned, but such queries will always assume that the result may contain multiple items.

In order to specify a single entity, the query must somehow identify just one instance. In WCF Data Services each entity has key properties, which serve this purpose. By specifying values for all of the key properties, any given entity instance is uniquely identified. Key lookup is a query (or part of query) which specifies the values for the key properties. So using key lookup we can ask for just one entity. Simple key lookup is like this:

http://host/service.svc/Products(1)

The above query returns a single entity or 404 response if the product specified doesn’t exist. Our Product entity has just one key property called ID and thus it’s not necessary to specify the name of the key property. The query above asks for product with its key property (ID) of value 1 (integer).

When such query is processed and translated into expression tree WCF Data Services will actually generate a query which asks for all products with ID equal to 1. Once that query returns its results, the service will verify that only one result was returned. So the above URL gets translated into expression tree like this one:

System.Collections.Generic.List`1[TypedService.Product].Where(element => (element.ID == 1))

It is pretty straightforward, it’s the query root followed by a filter which picks only products with ID equal to 1.

Note that we would get the exact same expression by running a URL query like:

http://host/service.svc/Products?$filter=ID eq 1

But the response for this query is different, it returns a list with a single item instead of the item itself directly.

Now let’s see what happens if the given entity has more than one key property. We will use an entity called Record which has two key properties; PartitionID which is an integer and RowID which is a string. A query for a single record looks like this:

http://host/service.svc/Records(PartitionID=1,RowID=’id0’)

The expression tree which is generated for this query is a bit different than what we could expect. WCF Data Services will use a separate Where call for each key property it needs to filter the results on, so it looks like this:

System.Collections.Generic.List`1[TypedService.Record]
    .Where(element => (element.PartitionID == 1))
    .Where(element => (element.RowID == "id0"))

Note again that it is expected that such query returns at most one result. If that’s not true the service will fail with a 500 status code.

And that’s it, key lookups are really not complicated. In the next post we will look at our first navigations over navigation properties.