3

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

    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 变为“名称”,MaterialType 变为“ masterType”等)然后是否可以克隆我已经在内存中拥有的部分实体(假设它在内存中?)并重命名字段还是我仍然需要进行完全单独的查询?

4

1 回答 1

2

如果我能负担得起,我想我会将这两个案例“合并”为一个预测。这将大大简化事情。但理解以下几点非常重要:

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

背景: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很容易实现。但每次进入 Sessions List 视图时都需要一次服务器访问。

CCJS 的设计目标之一是,一旦加载,它应该能够完全脱机运行,对服务器的访问为零。当连接断断续续且较差时,它应该可以正常工作。

CCJS 是您随时可用的会议指南。它会立即告诉您可用的课程、时间和地点,这样您就可以在走在大厅时找到您想要的课程,然后到达那里。如果您去过技术会议或酒店,您就会知道 wifi 通常很糟糕,而且如果应用程序只有在直接访问服务器时才能工作,它几乎是无用的。

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

CCJS Jumpstart 是“服务器独立”路径的一部分;您很快就会看到更接近于完全离线实现的东西。

您还将失去导航到相关实体的能力。会话列表显示每个会话的轨道、时间段和房间。这是在“查找”参考实体中找到的重复信息。您要么必须扩展投影以将此信息包含在会话的“扁平化”视图中(更大的有效负载),要么在客户端变得聪明并手动修补轨道、时间段和房间数据(复杂性)。

#2有助于离线/间歇性连接场景。当然,您必须设置消息系统,建立有关已保存实体的协议,并教会话列表查找和更新受影响的会话投影对象。这并不是特别困难——BreezeEntityManager发布的事件可能就足够了——但它需要更多的代码。

#3有利于“服务器独立性”,具有较小的投影负载,超级简单,并且是微风的炫酷演示。您必须管理isPartial标志,以便始终知道缓存中的会话是否完整。这并不难。

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

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

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

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

我自己喜欢cast-to-entity 方法,因为它很简单,而且在大多数情况下都能很好地工作。在做出选择之前,我确实会仔细考虑过这个选择。

概括

  1. 您不必投影查询结果转换为实体
  2. 如果它们是只读的,您可以直接绑定到投影数据,而无需 Knockout 可观察属性
  3. 确保您有充分的理由将投影数据转换为(部分)实体。

CCJS 有充分的理由将投影查询数据转换为实体。你?

于 2013-07-31T21:30:50.370 回答