Set Based Operations in Ado.net Data Services Part II

As an extension to the last blog post dealing with Set based filter operations in our client library ,
we will introduce support for the specifying method calls in the filter expression.

What does this achieve ?
Currently , the IsIn operator only supports an equality comparision.
With support for Method Calls , you can now select entities in a set which when passed to a method , evaluate true. ex: You can generate Uris such as this :

  1. /northwind.svc/Customers?$filter = substringof('London',City) or substringof('Berlin',City) or substringof('Prague',City)
  2. /northwind.svc/Customers?$filter = startswith('London',City) or startswith('Berlin',City) or startswith('Prague',City)
  3. /northwind.svc/Customers?$filter = endswith('London',City) or endswith('Berlin',City) or endswith('Prague',City)

Fortunately , not a lot of code change is required to get this support.

We will change the first parameter of the extension method from

 Expression<Func<TEntity, object>> propertyExpression

to

 Expression<Func<TEntity, TValue, bool>> comparisionInvokeExpression

which means that where we were initially sending an expression that selects a property of the entity , we now send the Extension method a delegate that accepts the entity and the value being compared against it and returns a boolean value after comparison using a method.

example :

 Expression<Func<T, object>> propertyExpression means
 customer => customer.City
 Expression<Func<TEntity, TValue, bool>> comparisionInvokeExpression means

 (cust, cityName) => cust.City.ToLower().StartsWith(cityName)

The second change is in the location where we build the comparision expression for values in the set.
we change the line which does the comparision using Expression.Equal with a method call to the comparision expression passed in .
We will changeĀ  :

 //Build a comparision expression which equats the Id of the ENtity with this value in the IDs list
// ex : e.Id == 1
Expression comparison = Expression.Equal(left, Expression.Constant(id));

to :

 //The Left Hand Side of the Filter Expression
MethodCallExpression comaprisionMethod = comparisionInvokeExpression.Body as MethodCallExpression;
 //Build a comparision expression which calls the method that does the comparision for us
//ex : c=> c.City.Contains(id)
Expression comparison = Expression.Call(
                        comaprisionMethod.Object,
                        comaprisionMethod.Method,
                        Expression.Constant(id) );

The complete code sample is here :