Raven如何知道要包含哪些系列?

时间:2013-08-21 01:17:36

标签: c# linq indexing ravendb

我正在查看以下示例代码以包含引用文档并避免往返。

var order = session.Query<Order>()
   .Customize(x => x.Include<Order>(o=>o.CustomerId)) // Load also the costumer
   .First();
var customer = session.Load<Customer>(order.CustomerId);

我的问题是Raven如何知道这个o=>o.CustomerId暗示Customer文件/收藏?在查询中提供的实体Customer从来没有获得Order实体。然而Raven声称获得Customer的第二个查询可以针对缓存完成,无需任何网络旅行。

如果是通过命名约定,这似乎是一个非常差/脆弱/脆弱的约定,当我需要包含多个文档时会发生什么?

EG。一辆汽车是以2个名字购买的,所以我想链接回2个客户,即主要和次要客户/司机。它们都存储在Customer集合中。

var sale = session.Query<Sale>()
   .Customize(x => x.Include<Sale>(o=>o.PrimaryCustomerId).Include<Sale>(o=>o.SecondaryCustomerId)) // Load also the costumer
   .First();
var primaryCustomer = session.Load<Customer>(order.PrimaryCustomerId);
var secondaryCustomer = session.Load<Customer>(order.SecondaryCustomerId);

如何在1次网络旅行中完成上述操作? Raven甚至会知道这个o=>o.PrimaryCustomerIdo=>o.SecondaryCustomerId是对同一个表Customer的引用,因为显然属性名称和集合名称没有对齐?

1 个答案:

答案 0 :(得分:2)

Raven没有“表格”的概念。它确实知道“集合”,但它们只是一种便利机制。在幕后,所有文档都存储在一个大数据库中。制作“集合”的唯一方法是每个文档都有Raven-Entity-Name元数据值。

您展示的两个示例都将导致一次往返(每次)。你的代码看起来很好。

  

我的问题是Raven如何知道这个o=>o.CustomerId意味着客户文档/集合?客户在查询中始终没有提供订单实体。

不需要在查询中提供。只要存储在CustomerId文档的Sale字段中的数据是完整文档密钥,该文档就会返回到客户端并加载到会话中。

  

然而,Raven声称第二个获取客户的查询可以在缓存中完成,无需任何网络旅行。

这是对的。会话容器跟踪返回的所有文档 - 而不仅仅是查询结果中的文档。因此,稍后当您使用相同的文档密钥调用session.Load时,它已经在会话中使用它,因此无需返回服务器。

无论您是查询,加载还是包含 - 在将文档拉出会话之前,文档都不会反序列化为静态类型。这就是您在Customer来电中指定session.Load<Customer>类型的原因。

  

如果是通过命名惯例,这似乎是一个非常差/脆弱/脆弱的惯例采用......

不,它是存储在属性中的,它是一个文档键,例如"customers/123"。每个文档都可以通过文档密钥进行寻址,无论是否知道类的静态类型。

  

当我需要包含1个以上的文件时会发生什么?

完全相同的事情。可以包含或加载到会话中的文档数量没有限制。但是,您应该确保在using语句中打开会话,以便正确处理。该会话是“工作单元容器”。

  

Raven怎么会知道这个o=>o.PrimaryCustomerIdo=>o.SecondaryCustomerId是对同一个表Customer的引用,因为显然属性名称和集合名称没有对齐?

同样,字段的名称无关紧要。重要的是这些字段中的数据包含文档ID,例如"customers/123"。如果您没有存储完整的字符串标识符,那么您将需要在lambda表达式中构建文档键。换句话说,如果Sale.CustomerId仅包含数字123,那么您需要将其包含在.Include<Sale>(o=> "customers/" + o.CustomerId)中。