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.PrimaryCustomerId
和o=>o.SecondaryCustomerId
是对同一个表Customer
的引用,因为显然属性名和集合名不一致?
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.PrimaryCustomerId
和o=>o.SecondaryCustomerId
是对同一个表Customer的引用,因为显然属性名和集合名不一致?
同样,字段的名称是什么并不重要。重要的是,这些字段中的数据包含文档id,例如"customers/123"
。如果没有存储完整的字符串标识符,则需要在lambda表达式中构建文档键。换句话说,如果Sale.CustomerId
只包含数字123
,则需要将其与.Include<Sale>(o=> "customers/" + o.CustomerId)
一起包含。