Entities , How many ways do I count thee ?

Its a common ask that we introduce aggregating mechanisms in Data services so that one can do a Count of
the number of entities present in an EntitySet easily.
In this blog post , I will outline one method of implementing a “Count” method that works for you.

The interface to the count method will be

 http://<ServiceEndPoint>/Count?entitySetName='<entitySetName>'

Server-Side

On the server-side , we will write a Service Operation that takes the name of the EntitySet as an input parameter.

 [WebGet]
 public long Count(string entitySetName) {
 //Implementation goes here
 }

In your Service Operations / Interceptors ,  you have access to the CurrentDataSource which represents your data providers.

The entity sets are properties off of the CurrentDataSource. We will get the entityset off of the CurrentDataSource

and get the count of entities by casting it to IListSource.

 [WebGet]
public long Count(string entitySetName)  {

long countOfEntities = 0;

//Get the Property off of the CurrentDataSource
PropertyInfo esProperty = this.CurrentDataSource.GetType().GetProperty(entitySetName);

//Get the EntitySet off of the CurrentDataSource
object esValue = esProperty.GetValue(this.CurrentDataSource, null);

//Cast the EntitySet to IListSource
IListSource genericESList = esValue as IListSource;

//Get the count of entities by fetching the list and getting the value of its "Count" Property
countOfEntities = genericESList.GetList().Count;

return countOfEntities;
}

Client-Side

we will make an extension method on the data service context that takes the name of the entityset and returns the count.

 DataServiceContext nwContext = new DataServiceContext( new Uri("ServiceRoot") );
long countOfProducts = nwContext.Count("Products");

Extension method on the DataServiceContext to retrieve count of entities in entityset  on the server .

 public static long Count(this DataServiceContext context, string entitySetName) {
 //Call the ServiceOperation on the server side passing the entitySetNameas a parameter
 var results = context.Execute<long>(new Uri(String.Format("Count?entitySetName='{0}'", entitySetName),
   UriKind.RelativeOrAbsolute));
 //Get the result off of the IEnumerable
 long count = results.First<long>();
 //return the count
 return count;
}

Complete Sample Code :

Put this in your Service Code on the server .
 [WebGet]
[SingleResult]
public long Count(string entitySetName) {
long countOfEntities = 0;
if (entitySetName == null) {
  throw new ArgumentNullException("entitySetName");
}
//Get the Property off of the CurrentDataSource
PropertyInfo esProperty = this.CurrentDataSource.GetType().GetProperty(entitySetName);
if (esProperty == null) {
throw new ArgumentException(String.Format("No EntitySet named {0} found on the DataSource", entitySetName));
}
try {
 //Get the EntitySet off of the CurrentDataSource
 object esValue = esProperty.GetValue(this.CurrentDataSource, null);
 //Cast the entitySet to IListSource
 IListSource genericESList = esValue as IListSource;
 //If the cast succeeded
 if (genericESList != null) {
 countOfEntities = genericESList.GetList().Count;
 }
}
catch (Exception exception) {
throw new DataServiceException("'Count' method Failed with , see InnerException -->", exception);
}
return countOfEntities;
}
Put this in your client Code .
 public static class ClientExtensions {
/// <summary>
/// This Method returns the count of the number if entities present in an Entityset
/// </summary>
/// <param name="context">The DataServiceContext which contains the entities</param>
/// <param name="entitySetName">The EntitySetName whose entities should be counted</param>
/// <returns>The number of entities in the entityset</returns>
/// <example>
///  long countOfProducts = context.Count("Products");
/// </example> 
public static long Count(this DataServiceContext context, string entitySetName)
{
    //Call the ServiceOperation on the server side passing the entitySetName as a parameter
    var results = context.Execute<long>(
            new Uri(String.Format("Count?entitySetName='{0}'", entitySetName), UriKind.RelativeOrAbsolute)
            );
    //Get the result off of the IEnumerable
    long count = results.First<long>();
    //return the count
    return count;
}
}

In a future post , I will talk about how to off load the counting work to your database , if you have a relational database

as your backend.