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 :
- /northwind.svc/Customers?$filter = substringof('London',City) or substringof('Berlin',City) or substringof('Prague',City)
- /northwind.svc/Customers?$filter = startswith('London',City) or startswith('Berlin',City) or startswith('Prague',City)
- /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 :