查找子集合不包含项目的所有项目

时间:2012-12-05 19:51:54

标签: linq ravendb

假设:

public class Order
{
    public string Name {get;set;}
    public List<LineItem> LineItems {get; set;}
}

public class LineItem
{
   public string Product {get; set;}
   public int Quantity {get; set;}
}

我正在试图弄清楚如何构建一个查询,该查询将返回具有名为“Apple”的产品的LineItem的所有订单

3 个答案:

答案 0 :(得分:4)

我一直在考虑这个问题。它出现了几次。问题是Raven目前还没有处理!.Any()或.All()查询。

这个特殊的例子简化了问题,让我想到了不同的道路。我相信有一个解决方案。它需要对静态索引进行lucene查询:

public class Orders_ByProduct : AbstractIndexCreationTask<Order>
{
  public Orders_ByProduct()
  {
    Map = orders => from order in orders
                    select new
                    {
                        Product = order.LineItems.Select(x => x.Product)
                    };
  }
}

var ordersWithoutApple = session.Advanced
                                .LuceneQuery<Order, Orders_ByProduct>()
                                .Where("*:* AND -Product: Apple")

答案 1 :(得分:2)

您可以通过为查询创建索引来实现这一目标

public class GetOrdersByProductIndex: AbstractIndexCreationTask<Order,GetOrdersByProductIndex.Result>
{
  public class Result
  {
     public string Product {get; set;}
  }

  public GetOrdersByProductIndex()
  {
    Map = orders => from order in orders
                    select new
                    {
                        Product = order.LineItems.Select(x => x.Product)
                    };
  }
}

现在您可以使用此索引获取订单。您的查询应如下所示

 using(IDocumentSession session = docStore.OpenSession())
{
   var orders  = session.Query<GetOrdersByProductIndex.Result,GetOrdersByProductIndex>
                        .Where(x=>x.Product != "Apple")
                        .As<Order>()
                        .ToList()
}

请注意,默认情况下它只会返回128条记录(由于ravendb设置的限制),如果您的查询结果有超过128条记录,则应使用Take(recordsNeeded)函数来获取数据。

答案 2 :(得分:2)

我们能够通过与!.Any进行明确比较来解决RavenDB对false缺乏支持的问题,例如:

orders.Where(x => x.LineItems.Any(y => y.Product == "Apple") == false)