I’m trying to make an extension method for restrictions on a DateTime? property. It’s for a search query and I really don’t want to duplicate this code for all the possible date fields.
public static IQueryOver<T, T> WhereInOpenEndedDateRange<T>(this IQueryOver<T, T> query,
Expression<Func<object>> field,
DateTime? rangeFrom,
DateTime? rangeTo)
{
if(rangeFrom.HasValue && rangeTo.HasValue)
{
query.WhereRestrictionOn(field).IsBetween(rangeFrom.Value).And(rangeTo.Value);
}
else if (rangeFrom.HasValue)
{
//query.Where(() => /* help */ >= rangeFrom.Value);
}
else if (rangeTo.HasValue)
{
//query.Where(() => /* help */ <= rangeTo.Value);
}
return query;
}
I think I’m missing a fundamental aspect of expressions. Is it possible to pass in some form of Expression parameter and use it in the /* help */ spots?
Thanks
update
getting closer, but still feel so very far away…
else if (rangeFrom.HasValue)
{
var lt = Expression.LessThanOrEqual(field, Expression.Constant(rangeFrom, typeof(DateTime?)));
var b = Expression.Lambda<Func<bool>>(lt);
query.Where(b);
}
but this will not work as it’d be comparing Func<object> to DateTime?. How can I merge the original property expression into a new Func<bool> and preserve the needed bits to keep the NH QueryOver in tact?
After looking at NH source for QueryOverRestrictionBuilder I will do
string propertyName = ExpressionProcessor.FindMemberExpression(field.Body)
and build the Restrictions with Criteria methods.
Well I couldn’t figure out how to do this using an
signature, but this is only for DateTime?s anyway, so I don’t see how the restriction I added will make any difference.
Basically, you needed expression (field in your example) to exactly match the parameter you were sending in, i.e. x=>x.SomeNullableDateField. ‘x’ is the type of query you started out with
so it needed to be included in the type of expression being sent in. You also missed getting hold of that parameter, using
to use for constructing the comparison expressions.
You were on to converting the BinaryExpression to
Expression<Func<bool>>, but you had to take it one step further toExpression<Func<T, bool>>.Usage