我对linq很新,并希望通过扩展IQueryable来深入研究。我想创建一个查询日期范围的简单扩展方法。某些东西相当于:
IQuerable.Where(x => x.Date > fromDate && x.Date < toDate);
但是在日期上有一些额外的处理。我希望能够解析一个属性来执行查询,因此方法调用将类似于:
IQueryable.WhereDateRange(x => x.Date, fromDate, toDate);
IQueryable.WhereDateRange(x => x.AnotherDate, fromDate, toDate);
我一直在寻找类似下面的东西,但我不完全确定我在做什么
public static IQueryable<T> WhereDateRange<T>(this IQueryable<T> source, Func<T, DateTime> getter, DateTime from, DateTime to) {
//query here
}
这可能吗?如果可以,我该怎么做?
答案 0 :(得分:4)
未经测试,但是:
public static IQueryable<T> WhereDateRange<T>(
this IQueryable<T> source, Expression<Func<T, DateTime>> getter,
DateTime from, DateTime to)
{
Expression body = getter.Body;
var predicate = Expression.Lambda<Func<T, bool>>(
Expression.And(
Expression.GreaterThan(body, Expression.Constant(from)),
Expression.LessThan(body, Expression.Constant(to))
),
getter.Parameters);
return source.Where(predicate);
}
但是,有关信息;我通常假设范围是>= start
和< end
,所以我会使用Expression.GreaterThanOrEqual
。
让它更可重用(并注意到我在这里使用GreaterThanOrEqual
):
public static IQueryable<T> WhereInRange<T, TValue>(
this IQueryable<T> source, Expression<Func<T, TValue>> selector,
TValue from, TValue to)
{
Expression body = selector.Body;
var predicate = Expression.Lambda<Func<T, bool>>(
Expression.And(
Expression.GreaterThanOrEqual(
body, Expression.Constant(from, typeof(TValue))),
Expression.LessThan(
body, Expression.Constant(to, typeof(TValue)))
),
selector.Parameters);
return source.Where(predicate);
}
(在这种情况下需要在常量上指定TValue
,因为null
否则会导致大问题)