I have a DateRange class that I'd like to apply to an IQueryable as a where predicate, automatically using the begin and end dates and automatically using an open or closed interval.
public class DateRange
{
public DateTime? BeginDate { get; set; }
public DateTime? EndDate { get; set; }
public bool BeginInclusive { get; set; }
public bool EndInclusive { get; set; }
public DateRange()
{
BeginInclusive = true;
EndInclusive = false;
}
public IQueryable<T> Apply<T>( IQueryable<T> source, Expression<Func<T,DateTime>> dateField )
{
var result = source;
if (BeginDate.HasValue)
{
if (BeginInclusive)
result = result.Where( x => dateField >= BeginDate ); //does not compile
else
result = result.Where( x => dateField > BeginDate ); //does not compile
}
if (EndDate.HasValue)
{
if (EndInclusive)
result = result.Where( x => dateField <= EndDate ); //does not compile
else
result = result.Where( x => dateField < EndDate ); //does not compile
}
return result;
}
}
And I want to call it like this, DateField is any DateTime property of T.
DateRange d;
IQueryable<T> q;
q = d.Apply( q, x => x.DateField );
So I want to pass a member expression to the Apply method, and have it apply an appropriate where clause to the result set, but I cannot figure out how to get the dateField member expression embedded in the where predicate's expression. See lines "do not compile" in class above. I need to transform dateField somehow or build the predicate expression some other way, but I have no idea how to do so.
dateField >= BeginDate
usingExpression
class methods. – Postfixvar expr = Expression.GreaterThanOrEqual( dateField.Body, Expression.Constant( BeginDate ) ); result = result.Where( Expression.Lambda<Func<T, bool>>( expr ) );
– CrystallographyExpression.Lambda
. Your code throws an exception when I try it. Check out my answer. – Postfix