Reputation: 1781
I've an ASP.NET Web API 2 exposing an OData endpoint.
In the front-end I'm using ASP.NET MVC 5. To consume the endpoint I'm using a WCF Services References.
The problem I'm facing is that I need to retrieve a subset of rows from the endpoint given the list of IDs.
Here's the entity I'm using in the OData endpoint
class MyEntity
{
public int ID {get; set;}
public string Name {get; set;}
public int Age {get; set;}
}
Using LINQ I've solved this in other situations using the following statement
var result = entitiesContext.MyEntity
.Where(x => idsEmployees.Select(y => y).Contains(x.ID));
where idsEmployees is the lists of IDs of the employees I need to retrieve.
Using this statement in the current scenario I get the following exception:
Error translating Linq expression to URI: The method 'Contains' is not supported.
How can I solve this?
Thank you.
Upvotes: 1
Views: 441
Reputation: 1781
After some digging I found a solution in this blog
https://blogs.msdn.microsoft.com/phaniraj/2008/07/16/set-based-operations-in-ado-net-data-services/
Here's an extension method that solve the problem
/// <summary>
/// Retrieves the subset of entities in a table exposed through OData
/// </summary>
/// <typeparam name="T">Entity type</typeparam>
/// <typeparam name="U">Subset type</typeparam>
/// <param name="query"></param>
/// <param name="Set"></param>
/// <param name="propertyExpression"></param>
/// <returns></returns>
public static DataServiceQuery<T> SubSet<T, U>(
this DataServiceQuery<T> query,
IEnumerable<U> Set,
Expression<Func<T, U>> propertyExpression)
{
//The Filter Predicate that contains the Filter criteria
Expression filterPredicate = null;
//The parameter expression containing the Entity Type
var param = propertyExpression.Parameters.Single();
//Get Key Property
//The Left Hand Side of the Filter Expression
var left = propertyExpression.Body;
//Build a Dynamic Linq Query for finding an entity whose ID is in the list
foreach (var id in Set)
{
//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));
//Add this to the complete Filter Expression
// e.Id == 1 or e.Id == 3
filterPredicate = (filterPredicate == null)
? comparison
: Expression.Or(filterPredicate, comparison);
}
//Convert the Filter Expression into a Lambda expression of type Func<Lists,bool>
// which means that this lambda expression takes an instance of type EntityType and returns a Bool
var filterLambdaExpression =
Expression.Lambda<Func<T, bool>>(filterPredicate, param);
return (DataServiceQuery<T>)query.Where<T>(filterLambdaExpression);
}
and here's the way to use it
var result = entitiesContext.MyEntity.Subset<MyEntity, int>(idsEmployees, x => x.ID);
Upvotes: 1