使用 IsInDateTimeRange 扩展 IQueryable

Extending IQueryable with IsInDateTimeRange

所以我对一遍又一遍地重写相同的查询感到有些厌倦。

repo.Query().Where(stuff => stuff.Timestamp >= minTime && stuff.Timestamp <= maxTime && ...);

我想我应该用一个名为 IsInDateTimeRange 的方法扩展 IQueryable,然后像这样使用它

repo.Query().IsInDateTimeRange(stuff => stuff.Timestamp, minTime, maxTime) ...

这对于 IEnumerable 来说非常容易,只需一个 Func<T, DateTime> 和两个 DateTime,但是对于 IQueryable 我需要一个 Expression 而且我不太确定如何使用它。

这是我的尝试,但似乎没有用。

public static IQueryable<TValue> IsInDateTimeRange<TValue>(
        this IQueryable<TValue> self,
        Expression<Func<TValue, DateTime>> getMember,
        DateTime minTime,
        DateTime maxTime)
    {
        return self.Where(value => minTime >= getMember(value) && maxTime <= getMember(value));
    }

您可以根据传递给方法的 属性 访问表达式手动构建表达式来完成此操作:

public static IQueryable<TValue> IsInDateTimeRange<TValue>(
    this IQueryable<TValue> self,
    Expression<Func<TValue, DateTime>> getMember,
    DateTime minTime,
    DateTime maxTime)
{
    var getMemberBody = getMember.Body;
    var filter = Expression.Lambda<Func<TValue, bool>>(
        Expression.And(
            Expression.LessThanOrEqual(
                Expression.Constant(minTime),
                getMemberBody
            ),
            Expression.LessThanOrEqual(
                getMemberBody,
                Expression.Constant(maxTime)
            )
        ),
        getMember.Parameters
    );
    return self.Where(filter);
}