使用Any的LINQ RavenDB子集合查询,不能在查询中包含非索引变量

时间:2015-05-21 01:42:46

标签: c# linq ravendb

我一直在寻找,似乎无法找到答案。

想象一下,我有以下内容:

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,此查询无效,&#34;无法查询未编入索引的字段&#34;。

我知道隐含的乌鸦在后台创建了一个索引。但是你究竟如何阅读外部变量并将其作为查询表达式的一部分包含在内?

我现在唯一的工作就是拥有不同的不同查询并首先检查标志,然后进行不同的查询。

我做错了吗?

提前致谢!

1 个答案:

答案 0 :(得分:2)

如果 - 在您的示例中就是这种情况 - “外部”标准不会转换为涉及查询的可访问字段之一的表达式,那么 - 除了事实不可能 - 它还没有感觉将它们包含在查询中。

对于你提供的相当人为的例子,你可以简单地这样做:

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设计,因为如果someOverridingFlagnull,则该方法不会按照其名称承诺执行。最好为两种不同的情况包含显式方法。

public List<EntityA> GetAllItemsGreaterThanTwenty();
public List<EntityA> GetAllItems();

另一个重要问题是,您是否对潜在的无限制结果集执行非分页查询。 RavenDB将限制结果数量,即如果可能匹配的数量超过128或服务器限制,您将无法获得所有结果。

有关这些主题的详情,请参阅http://ravendb.net/docs/article-page/2.0/csharp/intro/safe-by-defaulthttp://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/unbounded-results