使用 Any 的 LINQ RavenDB 子集合查询,不能在查询中包含非索引变量
LINQ RavenDB sub collection query using Any, cannot include non-indexed variables in query
我一直在四处寻找,但似乎找不到答案。
假设我有以下内容:
public class EntityA
{
public string EntityAID { get; set; }
public List<EntityB> Versions { get; set; }
}
public class EntityB
{
public int Cost { get; set; }
}
public List<EntityA> GetAllItemsGreaterThanTwenty(bool? someOverridingFlag)
{
using(var session = GetSession())
{
var entityAList = from entA in session.Query<EntityA>()
where entA.Versions.Any(entB => someOverridingFlag == null || entB.Cost > 20)
select entA
return entityAList.ToList();
}
}
所以问题在于,由于 someOverridingFlag,此查询不起作用,"cannot query on fields that are not indexed"。
我知道 raven 在后台隐式创建索引。但是,您究竟如何读取外部变量并将其也包含在查询表达式中呢?
我现在唯一的解决办法是进行不同的查询,先检查标志,然后再进行不同的查询。
我做错了什么吗?
提前致谢!
如果 - 正如您的示例中的情况 - "external" 条件未转换为涉及查询的可访问字段之一的表达式,那么 - 除了不可能的事实 - 它也 没有意义将它们包含在查询中。
对于您提供的相当人为的示例,您可以简单地这样做:
public List<EntityA> GetAllItemsGreaterThanTwenty(bool? someOverridingFlag)
{
using(var session = GetSession())
{
if (someOverridingFlag == null)
return session.Query<EntityA>().ToList(); // Note: unbounded result set will be limited to max 128 docs
else
return (from entA in session.Query<EntityA>()
where entA.Versions.Any(entB => entB.Cost > 20)
select entA).ToList();
}
}
但这将是一个非常糟糕的 API 设计,因为如果 someOverridingFlag
是 null
,则该方法不会执行其名称所承诺的内容。最好包括针对两种不同情况的显式方法。
public List<EntityA> GetAllItemsGreaterThanTwenty();
public List<EntityA> GetAllItems();
另一个重要问题是,您正在对可能 无限结果集 执行非分页查询。 RavenDB 会限制结果的数量,即如果可能匹配的数量超过 128 或服务器限制,您将不会获得所有结果。
有关这些主题的更多信息,请参阅 http://ravendb.net/docs/article-page/2.0/csharp/intro/safe-by-default and http://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/unbounded-results。
我一直在四处寻找,但似乎找不到答案。
假设我有以下内容:
public class EntityA
{
public string EntityAID { get; set; }
public List<EntityB> Versions { get; set; }
}
public class EntityB
{
public int Cost { get; set; }
}
public List<EntityA> GetAllItemsGreaterThanTwenty(bool? someOverridingFlag)
{
using(var session = GetSession())
{
var entityAList = from entA in session.Query<EntityA>()
where entA.Versions.Any(entB => someOverridingFlag == null || entB.Cost > 20)
select entA
return entityAList.ToList();
}
}
所以问题在于,由于 someOverridingFlag,此查询不起作用,"cannot query on fields that are not indexed"。
我知道 raven 在后台隐式创建索引。但是,您究竟如何读取外部变量并将其也包含在查询表达式中呢?
我现在唯一的解决办法是进行不同的查询,先检查标志,然后再进行不同的查询。
我做错了什么吗?
提前致谢!
如果 - 正如您的示例中的情况 - "external" 条件未转换为涉及查询的可访问字段之一的表达式,那么 - 除了不可能的事实 - 它也 没有意义将它们包含在查询中。
对于您提供的相当人为的示例,您可以简单地这样做:
public List<EntityA> GetAllItemsGreaterThanTwenty(bool? someOverridingFlag)
{
using(var session = GetSession())
{
if (someOverridingFlag == null)
return session.Query<EntityA>().ToList(); // Note: unbounded result set will be limited to max 128 docs
else
return (from entA in session.Query<EntityA>()
where entA.Versions.Any(entB => entB.Cost > 20)
select entA).ToList();
}
}
但这将是一个非常糟糕的 API 设计,因为如果 someOverridingFlag
是 null
,则该方法不会执行其名称所承诺的内容。最好包括针对两种不同情况的显式方法。
public List<EntityA> GetAllItemsGreaterThanTwenty();
public List<EntityA> GetAllItems();
另一个重要问题是,您正在对可能 无限结果集 执行非分页查询。 RavenDB 会限制结果的数量,即如果可能匹配的数量超过 128 或服务器限制,您将不会获得所有结果。
有关这些主题的更多信息,请参阅 http://ravendb.net/docs/article-page/2.0/csharp/intro/safe-by-default and http://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/unbounded-results。