首页 文章

RavenDB - DateTime.Subtract查询异常

提问于
浏览
1

尝试在ravendb上执行以下查询时

RavenSession.Query<R>().Any( x => DateTime.Now.Subtract( x.Submitted).TotalSeconds < 61)

抛出一个参数异常(“无法理解表达式”) .

当此代码被重写为

RavenSession.Query<R>().Any( IsSpam())

IsSpam定义为:

protected Func<R, bool> IsSpam()
    {
        return r => DateTime.Now.Subtract(r.Submitted).TotalSeconds < 61;
    }

代码执行顺利 . 两个查询之间的执行有什么区别?

2 回答

  • 0

    您不能在RavenDB中执行类似的查询 . 并且IsSpam方法可能正在做一些你不期望的事情 . 您的查询的问题是您需要我们进行计算才能回答它 . 这意味着我们无法将查询优化为索引搜索 . 我们不允许此类查询 .

    而是,使用此查询:

    var cutoff = DateTime.Now + TimeSpan.FromSeconds(61);
    
    RavenSession.Query<R>.Where(x=>x.Submitted > cutoff).ToList();
    
  • 0

    表达式树解析变得很复杂,我继续进行,虽然我不确定你发布的代码是否完全正确 IsSpam() 实现,但我不确定 r 参数会如何进入,正如它现在写的 .

    它可能与第一个示例中创建的闭包以及外部值如何泄漏到其中有关,而第二个示例作为 Func 更明确,这将不允许那些疯狂的闭包事件发生 .

    无论如何,Raven的LINQ提供者的观点是采用提供的表达式树并将其发送到服务器并让服务器能够将其转换为Lucene查询语法 . 像所有的抽象一样,它会泄漏,所以并非一切皆有可能,但通常更简单的事情比复杂或迂回的事情更好 .

    使用标准运算符可能更好,而不是使用DateTime的Subtract方法:

    RavenSession.Query<R>().Any(x => (DateTime.Now - x.Submitted).TotalSeconds < 61)
    

    我希望,由它创建的表达式树将与您的第一个表达树有很大不同(并且可能更容易解析) .

    此外,我必须添加,请小心在查询中使用DateTime.Now . 每次运行查询时,该值显然会有所不同,因此您永远无法利用Raven客户端缓存结果的能力 .

相关问题