Share via


Passing multiple values in a Where clause when calling RIA services from Silverlight

We recently worked on a project where we wanted to pass multiple values in a Where clause when calling RIA services. The issue seems trivial when we think of where...in clause in TSQL, but for RIA services, we need a little extra tricks. Rather than letting the good research go waste, I am publishing the details here.

Say, you have a Product-related database table which is mapped into "Product" entity inside RIA ___domain services. The context is named as "productContext". Product entity contains ProductID and few other columns. We want to query the Product entity for ProductID=10,20,30. So, lets write the query:

 EntityQuery<Product> listProduct = from p in productContext.GetProductsQuery()
 where p.ProductID in (10,20,30)
 select p;
 

Guess what, it does not work in RIA context. The "in" is not a valid syntax when calling RIA services.

Good news is, you can build a predicate expression that does exactly what "in" would do.

 

Expression:

 static Expression<Func<Product, bool>> BuiltInExpression(int[] ids) 
{ 
 var inputExpression = Expression.Parameter(typeof(Product), "input"); 
 var valueExpression = Expression.Property(inputExpression, s_propertyInfo); 
 var inExpression = 
 ids 
 .Aggregate( 
 default(Expression), 
 (acc, v) => 
 { 
 var vExpression = Expression.Constant(v, typeof(int?)); 
 var compareExpression = Expression.Equal(valueExpression, vExpression); 
 if (acc == null) 
 { 
 return compareExpression; 
 } 
 return Expression.OrElse(acc, compareExpression); 
 }); 
 
 inExpression = inExpression ?? Expression.Constant(true); 
 return Expression.Lambda<Func<Product, bool>>( 
 inExpression, 
 inputExpression 
 );} 
 

Calling the Expression

 static void Main(string[] args)
{
 var ids = new[] { 10, 20,30};
 var inExpression = BuiltInExpression (ids);
 
 EntityQuery<Product> listQuery = ProductContext.GetProductsQuery().Where(inExpression);
 TestGrid.ItemsSource = ProductContext.Load(listQuery).Entities;
}