【问题标题】:Extending IQueryable with IsInDateTimeRange使用 IsInDateTimeRange 扩展 IQueryable
【发布时间】:2018-02-14 19:30:26
【问题描述】:

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

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

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

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

这对于IEnumerable 来说非常容易,只需一个Func&lt;T, DateTime&gt; 和两个DateTimes,但是对于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));
    }

【问题讨论】:

  • 当你说不工作时,请解释它是什么意思。例外?编译错误?..
  • 由于getMember(value) 噪音,大多数 Linq 提供程序无法将转换后的表达式转换为商店查询。您必须使用常规的 Expression.Property 访问器手动替换相关部分。
  • 是的,编译器错误。无法调用 getMember,因为它不是委托。

标签: c# linq extension-methods iqueryable linq-expressions


【解决方案1】:

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

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);
}

【讨论】:

  • 打败我。我可能做的唯一调整是您实际上不需要接受getMember.Parameters.First()。您应该能够将getMembers.Parameters 作为第二个参数传递给Lambda&lt;&gt;()。另外,第一个LessThanOrEqual 应该是GreaterThanOrEqual :)。
  • 为您修复了小逻辑错误(您使用了两次&lt;=)。
  • Um 是有意的 ..min
  • (facepalm) 我还没有喝咖啡。已恢复!
  • @jool 如果此答案解决了您的问题,请通过将其标记为已接受来奖励 Titan。这将使他获得他所获得的声誉点数:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
相关资源
最近更新 更多