如何在LINQ to RavenDB查询的WHERE子句中进行AND谓词

编程入门 行业动态 更新时间:2024-10-28 04:18:57
本文介绍了如何在LINQ to RavenDB查询的WHERE子句中进行AND谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有以下模型:

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

这就是查询的方式:

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

我想获取所有具有since并且NewState在"some state of interest"之前的StateChange.CreatedAt并且now和是"some state of interest").

I want to get the count for all Clip records that have a (StateChange.CreatedAt before since and NewState is "some state of interest") AND NOT have a (StateChange.CreatedAt before now and OldState is "some state of interest").

虽然以上使用的谓词在linq中可以对对象起作用,但它似乎在linq中却无法起作用(即不返回预期结果).我怀疑这是因为如果左侧的表达式的值为true,则永远不会对表达式&& !.p.StateChanges.Any....进行求值.有办法解决这个问题吗?

While the predicate used above works in linq to object, it doesn't seem to work in linq to raven (i.e. does not return the expected result). I suspect that this is because the expression && !.p.StateChanges.Any.... is never evaluated if the expression on the left-hand side evaluates to true. Is there a way to work around this?

推荐答案

与条件评估无关. &&效果很好.

It's not related to the evaluation of conditions. && works just fine.

问题在于RavenDB无法正确处理使用.All(...)或!.Any(...)的查询.这是由于raven的动态索引引擎评估linq语句的方式.它想为每个StateChange条目构建一个单独的索引条目,这不适用于需要考虑多个相关项(例如不同的状态更改)的操作.

The problem is that RavenDB doesn't properly handle queries that use .All(...) or !.Any(...). This is due to the way raven's dynamic index engine evaluates your linq statement. It wants to build a separate index entry for each of your StateChange entries, which won't work for operations that need to consider multiple related items, such as the different state changes.

在此处中已经记录了一个问题.在尝试以这种方式查询时,它在内部版本2151中已关闭,以抛出有意义的异常.也许将来某个时候,他们可以重新评估是否有某种方法可以真正正确地评估这些类型的查询.

There is an issue already logged for this here. It was closed in build 2151 to throw back a meaningful exception when you try to query in this way. Maybe at some future date they can reassess if there's some way to actually evaluate these types of queries properly instead.

更新

我一直在考虑您的挑战,并且另一个相关的人,并且能够提出一个新的建议.技术,使您可以执行此操作.它将需要一个静态索引和Lucene查询:

I've been thinking about your challenge, and another related one, and was able to come up with a new technique that will allow you to do this. It will require a static index and lucene query:

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

当然,如果您想要的话,您仍然可以对其进行统计.

Of course, you can still just take statistics on it if that's what you want.

更多推荐

如何在LINQ to RavenDB查询的WHERE子句中进行AND谓词

本文发布于:2023-10-14 21:31:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1492272.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:谓词   句中   如何在   RavenDB   LINQ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!