c# - 如何查询 RavenDb 中的展平子集合?需要索引?

标签 c# linq ravendb

我在 C# web 项目中使用 RavenDb。我有一个对象,我需要用每个子对象 1 行和一些根/父对象属性来查询它的子集合。
注意:这不是实际设计,只是针对此问题进行了简化。

    public class OrderLine
    {
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime? ShipDate { get; set; }
    }
    public class Order
    {
        public int OrderId { get; set; }
        public string CustomerName { get; set; }
        public DateTime OrderDate { get; set; }
        public List<OrderLine> OrderLines { get; set; }

    }

带有订单行的订单是一个单独的文档。 ShipDate 将在每一行更新,因为并非所有产品都始终有货。

我需要能够创建包含以下列的最近 10 件产品的列表:

OrderId
Customer
ProductName
ShipDate

这不起作用,因为不支持 SelectMany:

        var query = from helper in RavenSession.Query<Order>()
                        .SelectMany(l => l.OrderLines, (order, orderline) => 
                            new { order, orderline })
                    select new 
                    {
                        helper.order.OrderId,
                        helper.order.CustomerName,
                        helper.orderline.ProductName,
                        helper.orderline.ShipDate

                    };
        var result = query.Where(x => x.ShipDate.HasValue)
            .OrderByDescending(x => x.ShipDate.Value).Take(10);

我认为正确的做法是创建一个索引来使列表变平,但我没有取得任何成功。我不相信 Map-Reduce 情况会起作用,因为据我所知,它会有效地进行分组,从而将文档数量减少到更少的行(在索引中)。但在这种情况下,我试图将文档数量扩展到更多行(在索引中)。

我不想将每个 OrderLine 放在一个单独的文档中,但我不知道我的选择是什么。

最佳答案

由于您希望按子类中的字段进行过滤和排序,因此您需要确保对所有需要的字段进行索引和存储

public class ShippedItemsIndex
    : AbstractIndexCreationTask<Order, ShippedItemsIndex.Result>
{
    public class Result
    {
        public int OrderId { get; set; }
        public string CustomerName { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime ShipDate { get; set; }
    }

    public ShippedItemsIndex()
    {
        Map = orders => 
            from order in orders
            from line in order.OrderLines
            where line.ShipDate != null
            select new
            {
                order.OrderId,
                order.CustomerName,
                line.ProductName,
                line.Quantity,
                line.ShipDate
            };

        StoreAllFields(FieldStorage.Yes);
    }
}

然后你可以project from the index进入你的结果。

var query = session.Query<Order, ShippedItemsIndex>()
    .ProjectFromIndexFieldsInto<ShippedItemsIndex.Result>()
    .OrderByDescending(x => x.ShipDate)
    .Take(10);

var results = query.ToList();

Here is a complete test demonstrating.

关于c# - 如何查询 RavenDb 中的展平子集合?需要索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21083222/

相关文章:

c# - 在 ASP.NET 中调用远程 Web 服务

c# - 从 64 位应用程序调用 Twain 驱动程序

c# - 如何使用 Linq Lambda 检索 XML?

Monotouch 中的 Linq(在设备上调试)

.net - RavenDB 在模型命名空间更改后抛出转换异常

c# - LINQ to XML - 将节点添加到 .csproj 文件

c# - 从桌面应用程序使用时的 PasswordVault 安全性

c# - linq groupby 问题

.net - 将 RavenDB 用于具有复杂用户对象权限模型的解决方案

RavenDB 应用程序级别的修订管理