来自已加载实体的Breeze投影查询

时间:2013-07-31 15:01:24

标签: breeze

如果我使用breeze加载部分实体:

    var query = EntityQuery.from('material')
        .select('Id, MaterialName, MaterialType, MaterialSubType')
        .orderBy(orderBy.material);

        return manager.executeQuery(query)
            .then(querySucceeded)
            .fail(queryFailed);

        function querySucceeded(data) {
            var list = partialMapper.mapDtosToEntities(
                manager, data.results, entityNames.material, 'id');
            if (materialsObservable) {
                materialsObservable(list);
            }
            log('Retrieved Materials from remote data source',
                data, true);
        }

...而且我也希望从同一个实体(例如可能还有其他一些字段)中获得另一个稍微不同的部分查询,然后我假设我需要执行另一个单独的查询,因为这些字段未被检索在第一个查询?

好的,那么如果我想使用第一个查询中检索到的相同字段(Id,Materialname,MaterialType,MaterialSubType),但我想在第二个查询中调用这些字段的不同名称(Materialname变为“name”, MaterialType变为“masterType”等等然后是否可以克隆我已经在内存中的部分实体(假设它在内存中?)并重命名字段或者我是否还需要进行完全独立的查询?

1 个答案:

答案 0 :(得分:2)

我想我会"结合"如果我能负担得起,将这两个案例分成一个投影。这将大大简化事情。但理解以下几点非常重要:

您无需将查询投影结果转换为实体!

Backgound:CCJS示例

您可能已经从John Papa的精彩PluralSight课程" Single Page Apps JumpStart"中了解了CCJS示例中的投影到实体技术。 CCJS使用此技术的原因非常具体:可以简化列表更新而无需访问服务器

考虑CCJS"会话列表"由投影查询填充。 John没有必要将查询结果转换为实体。他本可以直接与预期结果联系起来。请记住,Knockout很高兴地绑定到原始数​​据值。用户从不直接编辑该列表上的会话。如果显示的会话值无法更改,则将其转换为可观察的属性会浪费CPU。

当您点击会话时,您将转到会话视图/编辑屏幕,该屏幕几乎可以访问整个会话实体的每个属性。 CCJS需要那里的完整实体,因此它在缓存中查找完整(非部分)会话,如果没有找到,则从服务器加载实体。即使到目前为止,将原始投影结果转换为(部分)会话实体也没有特别的价值。

现在编辑会话 - 更改标题 - 并保存。返回"会话列表"

问题

如何确保更新的标题出现在会话列表中?

如果我们将Sessions List HTML绑定到投影数据对象,那么这些对象不是实体。他们只是对象。您在会话视图中编辑的实体不是“会话列表”中显示的集合中的对象。是的,列表中有一个对应的对象 - 具有相同会话id的对象。但它不是同一个对象

选择

#1 :重新发布投影查询,从服务器刷新列表。直接绑定到投影数据。请注意,数据由原始JavaScript对象组成,而不是实体;它们不在Breeze缓存中。

#2 :保存真实会话实体后发布事件;订阅"会话列表" ViewModel会听到事件,提取更改,并更新列表中会话的副本。

#3 :使用投影到实体技术,以便您可以在任何地方使用会话实体。

优点和缺点

#1 易于实施。但是每次进入“会话列表”视图时都需要服务器跳闸。

CCJS的一个设计目标是,一旦加载,它应该能够完全脱机操作,无需访问服务器。当连接断断续续且很差时,它应该工作得很清晰。

CCJS是您随时准备的会议指南。它会立即告诉您哪些会话可用,何时何地可以找到您想要的会话,因为您正在走廊,然后到达那里。如果你去过技术会议或酒店,你就会知道无线网络通常很糟糕,如果只有在可以直接访问服务器的情况下才能使用该应用程序。

#1不太适合CCJS的预期操作环境。

CCJS Jumpstart是一个与服务器无关的部分"路径;您很快就会看到更接近完整离线实施的内容。

您也将失去导航到相关实体的能力。会话列表显示每个会话的轨道,时间段和房间。在"查找"中找到了重复的信息。参考实体。您必须扩展投影以将此信息包含在"展平的"会话视图(更有效的有效载荷)或在客户端获得智能,并手动修补轨道,时间段和房间数据(复杂性)。

#2 有助于离线/间歇性连接方案。当然,您必须设置消息传递系统,建立有关已保存实体的协议,并教授会话列表以查找和更新受影响的会话投影对象。这不是一件非常困难的事--Breeze EntityManager发布的事件可能就足够了 - 但需要更多的代码。

#3 有利于"服务器独立性",具有较小的投影有效负载,非常简单,并且是一个很酷的微风示范。您必须管理isPartial标志,以便始终知道缓存中的会话是否完整。这并不难。

如果你需要多种口味的“部分实体”,它可能会变得更加复杂。 ......这似乎是你要去的地方。这不是CCJS的问题。

John为CCJS选择#3,因为它符合应用目标。

这并不能使它成为每个应用程序的正确选择。它可能不是的正确选择

例如,如果您始终拥有快速,低延迟的连接,那么#1可能是您的最佳选择。我真的不知道。

我喜欢自己的演员到实体方法,因为它很容易并且在大多数时候都很好用。在我做之前,我确实仔细考虑过这个选择。

摘要

  1. 必须将投影查询结果转换为实体
  2. 如果它们是只读的,您可以直接绑定到投影数据,没有Knockout可观察属性
  3. 确保您有充分的理由将投影数据转换为(部分)实体。
  4. CCJS有一个很好的理由将投影查询数据转换为实体。你呢?