1

I've created an extension method on IQueryable that allows me to more succinctly filter on records where a date is between two specified values, like this:

query = query.WhereValueBetween(x => x.OrdShippingDate.Value, dateFrom, dateTo);

(Note the DateTime fields are nullable, hence I use ".Value", but that's not relevant to my question)

I want to be able to specify multiple fields to check, where only one of the fields needs to be between the specified dates, either like this:

query = query.WhereValuesBetween(dateFrom, dateTo, x => x.OrdShippingDate.Value, x => x.OrdDeliveryDate.Value, x => x.OrdReceivedDate.Value);

or something like this:

query = query.WhereValuesBetween(dateFrom, dateTo, x => new[] {x.OrdShippingDate.Value, x.OrdDeliveryDate.Value, x.OrdReceivedDate.Value });

I have no preference for either.

My original extension method looks like this:

public static IQueryable<TSource> WhereValueBetween<TSource, TCompare>
(
    this IQueryable<TSource> source, Expression<Func<TSource, TCompare>> selector,
    TCompare lowest, TCompare highest
)
{
    var pe = selector.Parameters.First();
    var memberExpression = (MemberExpression)selector.Body;
    BinaryExpression predicateBody = BetweenExpression(lowest, highest, memberExpression);

    var callExpression = Expression.Call(
        typeof(Queryable),
        "Where",
        new Type[] { source.ElementType },
        source.Expression,
        Expression.Lambda<Func<TSource, bool>>(predicateBody, new ParameterExpression[] { pe }));
    return source.Provider.CreateQuery<TSource>(callExpression);
}

How do I adapt this method to be able to use multiple values?

The reason I want to use expressions and not Funcs directly is because the Where expression gets passed to Entity Framework for execution and it's very important that my expression gets translated to SQL for execution for performance reasons.

I've tried changing the signature to:

public static IQueryable<TSource> WhereValueBetween<TSource, TCompare>
(
    this IQueryable<TSource> source, List<Expression<Func<TSource, TCompare>>> selectors,
    TCompare lowest, TCompare highest
)

But then the 'pe' parameter expression would not match for each selector, which errors out.

I've also tried changing the signature to this:

public static IQueryable<TSource> WhereValueBetween<TSource, TCompare>
(
    this IQueryable<TSource> source, Expression<Func<TSource, TCompare[]>> selector,
    TCompare lowest, TCompare highest
)

But I have no idea how to extract the relevant expressions from 'TCompare'.

Govert
  • 13
  • 3

0 Answers0