Raven如何知道该包含哪些收藏

本文关键字:收藏 包含哪 何知道 Raven | 更新日期: 2023-09-27 18:28:28

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

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的第二个查询可以针对缓存进行,不需要任何网络旅行。

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

例如。一辆车是用两个名字购买的,所以我想链接回两个客户,主要和次要客户/司机。它们都存储在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);

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

Raven如何知道该包含哪些收藏

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

您展示的两个示例都将导致一次往返。你的代码在我看来很好。

我的问题是Raven如何知道这个o=>o.CustomerId意味着客户文档/集合?在任何时候都没有在查询中提供实体Customer来获取Order实体。

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

然而,Raven声称,在没有任何网络旅行的情况下,可以对缓存进行第二次查询以获得客户。

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

无论您是查询、加载还是包含,文档都不会被反序列化为静态类型,直到您将其从会话中取出。这就是在session.Load<Customer>调用中指定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)一起包含。