TL : DR - 使用 Big Data w/Breeze.js
我还没有找到最优雅的方法,寻找任何在查询大数据方面有一些良好经验并且仍然控制缓存的人 -
如果我出去点击服务器,假设我得到了 20k 条记录,每条记录都有一个 ID 和一个名称属性。 因为我想在与该数据集交互时使用我的缓存,所以我缓存数据并使用它做一些事情。
然后假设我想查看一组新数据,但不会丢失所有导航属性,所以我出去,点击服务器,向缓存添加更多实体,然后因为我喜欢查看我的数据,所以我执行一个选择查询来获取 POJO 的网格。
当我第一次访问服务器并缓存这些记录时,我不对本地缓存应用任何过滤器并不重要。 但是,第二次,我的缓存现在可能包含我想要使用的实体数量的两倍。
同样,我不想对数据进行大量复杂的过滤,这就是服务器的用途。
问题所在
我不能再在不使用相同查询参数的情况下命中我的本地缓存,这是不可能的(或在合理范围内)
由于我使用的是 Knockout.js 对于数据绑定,我需要在返回数据后对数据使用选择查询以获取 POJO(ko.toJS() 不会扁平化导航属性,ko.toJSON() 不适用于 Breeze 实体,因为它认为它们是递归的)
半途而废的解决方案
我可以创建我的 entityManager 的副本,再次获取导航属性,然后重新查询数据,但随后我不得不做很多额外的查询
我想做什么
清除该实体类型的缓存,以便当我用新实体重新填充它时,我可以获取该数据以使用。
没有清除特定实体类型的缓存的官方方法。你可以这样做
manager.getEntities('Foo').forEach(function(foo) {manager.detachEntity(foo);});
这是一种减法方法。如果您知道相关类型是什么,并且认为从新的管理器开始并添加相关类型比对您想要杀死的类型进行猛烈抨击会更快,则可以考虑加法方法。
我不认为这是你真正想做的,所以我只会为它编写伪代码。
-
提取相关类型:
var related = manager.getEntities(['a', 'b', 'c']);
。你只需要这样做一次;此后反复使用related
。 -
在下一个查询之前清除管理器:
manager.clear();
-
附加相关实体:
related.forEach(function(entity){manager.attachEntity(entity);});
-
执行下一个"foo"查询。
我不知道哪种方法更适合您的应用程序。
您可以建议(在用户语音中)一个新的 EntityManager 方法,该方法清除单个类型(或类型数组)的缓存。也许是EntityManager.clear()
方法的可选参数。我们在DevForce中有这样的东西。
一个完整的解决方案,但要对您的数据进行 JSON 处理,请使用以下命令:
ko.mapping.toJS(data, { ignore : ['entityAspect', 'entityType'] })