Open phatcher opened 5 years ago
I use the following extension method:
public static IBoundClient<TOwner> WhereInFilter<TOwner, TProperty>(
this IBoundClient<TOwner> client,
Expression<Func<TOwner, TProperty>> getter,
params TProperty[] propertyValues)
where TOwner : class
{
return client.Filter(CreateWhereInFilter(getter, propertyValues));
}
public static IBoundClient<TOwner> WhereInFilter<TOwner, TProperty>(
this IBoundClient<TOwner> client,
Expression<Func<TOwner, TProperty>> getter,
IEnumerable<TProperty> propertyValues)
where TOwner : class
{
return client.Filter(CreateWhereInFilter(getter, propertyValues));
}
private static Expression<Func<TOwner, bool>> CreateWhereInFilter<TOwner, TProperty>(Expression<Func<TOwner, TProperty>> getter, IEnumerable<TProperty> propertyValues)
{
// 1. Find the property accessor
var arg = getter.Parameters.First();
var property = (MemberExpression)getter.Body;
// 2. Create comparison chain
Expression comparisons = null;
foreach (var value in propertyValues)
{
var comparison = Expression.Equal(property, Expression.Constant(value));
if (comparisons == null)
{
comparisons = comparison;
}
else
{
comparisons = Expression.Or(comparisons, comparison);
}
}
// 3. Return the chained comparisons as a new predicate
return Expression.Lambda<Func<TOwner, bool>>(comparisons, arg);
}
Used like:
var foos = await this.ODataApi.For<Foo>()
.WhereInFilter(x => x.FooID, fooIds)
.FindEntriesAsync()
.ConfigureAwait(false);
@sixlettervariables Thanks, that's the sort of thing I was thinking of.
Think this should be in the library as it's a common problem and under the class of problem that it was intended to help with - mind adding it as a pull request once @object expresses an opinion?
Certainly, I'd enjoy some feedback on the naming of the API (and its shape) and where in the project it would best fit (i.e. new API on IBoundClient? Extension method?).
Any update here?
@sixlettervariables did you have a shared library for this?
Apologies @scsloan but in my current role I no longer actively use OData.
Say you are trying to restrict a query against a list of values that is supplied at runtime e.g.
You will get a syntax error saying that it can't turn System.Collection into a URI
It is possible to put this together like this..
But you have to take care with the type that's being encoded and its fairly hacky overall.
Suggest we look at a way of providing a helper that would do this sort of encoding, may be an overload of filter that takes a delegate and a collection?