我正在查看以下示例代码以包含引用文档并避免往返。
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.PrimaryCustomerId
和o=>o.SecondaryCustomerId
是对同一个表Customer
的引用,因为显然属性名称和集合名称没有对齐?
答案 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.PrimaryCustomerId
和o=>o.SecondaryCustomerId
是对同一个表Customer的引用,因为显然属性名称和集合名称没有对齐?
同样,字段的名称无关紧要。重要的是这些字段中的数据包含文档ID,例如"customers/123"
。如果您没有存储完整的字符串标识符,那么您将需要在lambda表达式中构建文档键。换句话说,如果Sale.CustomerId
仅包含数字123
,那么您需要将其包含在.Include<Sale>(o=> "customers/" + o.CustomerId)
中。