The inner workings of Count in RIA Services

One of things that came up repeatedly in our API Reviews for RIA Services was the fact that, we were requesting the total server count of the resulting query by default for paging scenarios.

This basically meant that were executing two queries on the database:-

  1. Execution on the actual query to get the resulting entities.
  2. Executing another query on to the server to figure out the total number of entities that meet the query.

This was never an issue for most non-paging scenarios as the framework was optimized for it. Here is the flow in the previous releases:-

  1. If query does not have Take, then the resulting entity count is the same as the total entity count for the query in the database.
  2. If query does have the Take, the framework used to send another query to the server to request the total entity count for the entity in the server.
    1: loadOp = ds.Load<Customer>(ds.GetCustomersQuery());
    2: loadOp.Completed += new EventHandler(loadOp_Completed);

The count for this query would by 91 entities and the total entity count will also be 91 (No of customers in Northwind database).

image 

In the latest RIA Services bits, we made a change where the count is not returned by default for paging scenarios.

Running a query like the one specified above will not have affect on the count and only one query will be executed on the server.

Now let’s modify the query to look like this and run it on the RC bits:-

 

 loadOp = ds.Load<Customer>(ds.GetCustomersQuery().Take(10));
 loadOp.Completed += new EventHandler(loadOp_Completed);

Now let’s look at the count returned from the server:-

image

As you can see the TotalEntityCount is –1.

So now the question arises is that how do i get the count when i add a take. All you need to do is to set the IncludeTotalCount property to true on the EntityQuery. Here is an example to do that:-

 EntityQuery <Customer>loadCustomers = ds.GetCustomersQuery();                   
 loadCustomers.IncludeTotalCount= true;
 loadOp = ds.Load<Customer>(loadCustomers.Take(10));

Here are the results:-

image 

DomainDataSource has been optimized to take this change into account and it will not request for count in non-paging scenarios. As soon as a page size is specified, DomainDataSource will set the IncludeTotalCount property on the EntityQuery for you. You can always override this behavior by subscribing to the LoadingData event on the DomainDataSource.

Cheers!