使用IsInDateTimeRange扩展IQueryable

joo*_*ool 4 c# linq extension-methods iqueryable linq-expressions

所以我有点厌倦了一遍又一遍地重写相同的查询.

repo.Query().Where(stuff => stuff.Timestamp >= minTime && stuff.Timestamp <= maxTime && ...);
Run Code Online (Sandbox Code Playgroud)

我以为我应该IQueryable使用一个名为的方法进行扩展IsInDateTimeRange,并像这样使用它

repo.Query().IsInDateTimeRange(stuff => stuff.Timestamp, minTime, maxTime) ...
Run Code Online (Sandbox Code Playgroud)

这将是非常容易的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));
    }
Run Code Online (Sandbox Code Playgroud)

Tit*_*mir 8

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

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);
}
Run Code Online (Sandbox Code Playgroud)