如何在LINQ到RavenDB查询中的WHERE子句中使用和谓词

如何在LINQ到RavenDB查询中的WHERE子句中使用和谓词,linq,ravendb,Linq,Ravendb,我有以下型号: public class Clip { public Guid ClipId { get; set; } public IList<StateChange> StateChanges { get; set; } } public class StateChange { public string OldState { get; set; } public string NewState { get; set; } public

我有以下型号:

public class Clip {
    public Guid ClipId { get; set; }
    public IList<StateChange> StateChanges { get; set; }
}

public class StateChange {
    public string OldState { get; set; }
    public string NewState { get; set; }
    public DateTime ChangedAt { get; set; }
}
公共类剪辑{
公共Guid ClipId{get;set;}
公共IList状态更改{get;set;}
}
公共阶级国家变革{
公共字符串OldState{get;set;}
公共字符串NewState{get;set;}
公共日期时间更改日期{get;set;}
}
这就是查询raven的方式:

var now = DateTime.UtcNow;
var since = now.AddSeconds(60);
string state = "some state of interest";
using (var session = docStore.OpenSession()) {
            RavenQueryStatistics stats;
            session.Query<Clip>()
                .Statistics(out stats)
                .Where(
                    p => p.StateChanges.Any(a => (since > a.ChangedAt && a.NewState == state))
                    && !p.StateChanges.Any(a => (a.OldState == state && now > a.ChangedAt)))
                .ToArray();
            return stats.TotalResults;
        }
var now=DateTime.UtcNow;
var-since=now.AddSeconds(60);
string state=“某些感兴趣的状态”;
使用(var session=docStore.OpenSession()){
拉文奎尔统计数据;
session.Query()
.统计数据(统计数据)
.在哪里(
p=>p.StateChanges.Any(a=>(自>a.ChangedAt&&a.NewState==state))
&&!p.StateChanges.Any(a=>(a.OldState==state&&now>a.ChangedAt)))
.ToArray();
返回stats.TotalResults;
}
我想获得所有
剪辑
记录的计数,这些记录在
之前有(
StateChange.CreatedAt
,因为
NewState
“某些感兴趣的状态”
),而在
现在
之前没有(
StateChange.CreatedAt
OldState
“某些感兴趣的状态”


虽然上面使用的谓词在LINQtoObject中有效,但在LINQtoRaven中似乎不起作用(即,不返回预期结果)。我怀疑这是因为表达式
&&!。p、 StateChanges。如果左侧的表达式计算结果为true,则不会计算任何..
。有办法解决这个问题吗?

它与条件评估无关很好用

问题是RavenDB不能正确处理使用.All(…)或!的查询!。任何(…)。这是因为raven的动态索引引擎评估linq语句的方式。它希望为每个状态更改条目建立单独的索引条目,这对于不需要考虑多个相关项的操作(如不同的状态更改)是不起作用的。 已经为此记录了一个问题。它在构建2151中关闭,以便在您尝试以这种方式查询时抛出一个有意义的异常。也许在将来的某个日期,他们可以重新评估是否有某种方法可以真正正确地评估这些类型的查询

更新

我一直在考虑你的挑战,并且,能够想出一种新的技术,让你做到这一点。它需要静态索引和lucene查询:

public class Clips_ByStateChange : AbstractIndexCreationTask<Clip>
{
  public Clips_ByStateChange()
  {
    Map = clips =>
          from clip in clips
          select new {
              OldState = clip.StateChanges
                  .Select(x => x.OldState + "|" + x.ChangedAt.ToString("o")),
              NewState = clip.StateChanges
                  .Select(x => x.NewState + "|" + x.ChangedAt.ToString("o"))
          };
  }
}

var results = session.Advanced.LuceneQuery<Clip, Clips_ByStateChange>()
    .Where(string.Format(
        "NewState: {{{0}|* TO {0}|{1}}} AND -OldState: {{{0}|* TO {0}|{2}}}",
        state, since.ToString("o"), now.ToString("o")));
public类Clips\u ByStateChange:AbstractIndexCreationTask
{
公共剪辑_ByStateChange()
{
地图=剪辑=>
从剪辑剪辑
选择新的{
OldState=clip.StateChanges
.选择(x=>x.OldState+“|”+x.ChangedAt.ToString(“o”)),
NewState=clip.StateChanges
.选择(x=>x.NewState+“|”+x.ChangedAt.ToString(“o”))
};
}
}
var results=session.Advanced.LuceneQuery()
.Where(string.Format)(
“新闻状态:{{{0}{124;*至{0}{1}}}和-OldState:{{{0}{124;*至{0}{2}}”,
状态,自.ToString(“o”)、现在.ToString(“o”);

当然,如果这是你想要的,你仍然可以对它进行统计。

你说的“不起作用”是什么意思?是否有错误?否,这意味着它没有返回预期的结果,即忽略右侧表达式。您如何知道它忽略了它?如果第一个条件为true,则它必须计算正确的条件以获得整个条件结果。@AmiramKorach是,这是处理对象集合时它所做的。但如果谓词被转换为Lucene查询字符串,情况就不是这样了。