BreezeJS 意外混合缓存和服务器数据

BreezeJS mixing cache and server data unexpectedly

我在使用 Breeze 时遇到了一个奇怪的(或至少是意外的)问题。我有一个 EF back-end 视图模型,我向其发送了一些参数,它 return 发送了一些数据。我使用 withParameters 选项来执行此操作。 back-end 做了很多 Include 和投影,return 是我想在一组自定义视图模型实体(即不是数据库实体)中显示的数据。其中一个参数是我要为其显示数据的键列表。

虽然我检索的是 parent 的列表(例如键 [1,2] 表示 parent 实体中的哪些 children 我想检索它应该得到所有 Parent 个实体 Children 列表 属性 它们本身有一个 ToyId 属性 在键中有一个值和那些 Child实体)。换句话说,结构就像 Parent.Child[]Child.ToyId 我想得到 parents 和 children 有某些玩具和那些 children 自己(但不是其他 children)。 parent 和 child 集都很大,所以我在 SQL 中通过 EF 执行此操作(这本身就是一次冒险)。

无论如何,问题发生在我 select 两个密钥并获取数据然后 de-select 其中一个密钥之后。第一个查询获取两个键的数据,按预期工作。在第二个 executeQuery 的回调中,我得到了 与上一个查询 相同的数据,这意味着就好像我从未 de-select 编辑过密钥一样。我已经验证 Breeze 使用正确的 keys 参数值和 back-end returns just 数据命中 back-end 我想要,但似乎 Breeze 忽略了来自 back-end 的数据或对来自 back-end 及其缓存实体(对于两个键)的结果集执行联合并将该联合作为 results 进入回调,而不仅仅是服务器 returned。这是预期的行为吗?不幸的是,一切都是这样写的。我们(致力于此,我们第一个使用 Breeze 的项目)都假设它只会 return 服务器在不使用 executeQueryLocally 时发送的内容,因此重构将是一件大事。叹息

我尝试了一些 where 谓词,但它们不起作用,也看不出在 Breeze 端进行投影有何帮助。我想也许它认为查询是相同的,所以它 returned 缓存数据作为快捷方式,所以我添加了一个 where('Parent.Children', 'any', 'ToyId', 'in', keys),但这没有用,它仍然引入了 de-select编辑结果。

我发现解决这个问题的唯一方法是在进行任何查询之前通过 queryManager.clear(),我怀疑进行 noTracking 查询也可能有效(尽管没有实际实体objects)。我考虑过将 keys 参数转换为 where 过滤器并从那里获取它而不是 keys 参数,以防告诉 Breeze 仅显示 back-end 数据.

是否有 "correct" 方法只取回服务器在回调中发送的数据?

("The callback" 表示传递给 executeQuery.then(...) 的函数)

如您所见,Breeze 在调用您的回调方法之前将查询结果合并到缓存中。这意味着,在回调中,parent 实体将有 所有 的 children 存在于缓存中。

查询返回的实体数组在回调返回的 saveResult object 的 retrievedEntities 属性 中可用。您可以使用它来确定从查询中返回了哪些 children。

entityManager.executeQuery(query).then(function(data) {
    var parents = data.results;
    var ret = data.retrievedEntities;
    //... filter ret to get the children
    //... update viewmodel with children
});