Breeze 从已加载的实体执行投影查询

Breeze 从已加载的实体执行投影查询,breeze,Breeze,如果我使用breeze加载部分实体: var query = EntityQuery.from('material') .select('Id, MaterialName, MaterialType, MaterialSubType') .orderBy(orderBy.material); return manager.executeQuery(query) .then(querySucceeded)

如果我使用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”等等),那么是否可以克隆内存中已有的部分实体(假设它在内存中?)并重命名字段,还是我仍然需要执行完全独立的查询?

如果我有能力,我想我会将这两个案例“合并”为一个投影。这将大大简化事情。但理解以下几点非常重要:

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

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

以CCJS“会话列表”为例由投影查询填充。John不必将查询结果转换为实体。他可以直接绑定到投影结果。请记住,Knockout很乐意绑定到原始数据值。用户从不直接编辑该列表上的会话。如果显示的会话值无法更改,则将其转换为可观察属性es是对CPU的浪费

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

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

问题: 如何确保更新的标题显示在会话列表中

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

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

#2保存真实会话实体后发布事件;订阅的“会话列表”视图模型将听到事件,提取更改,并更新列表中会话的副本

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

利弊 #1易于实现。但每次进入会话列表视图时都需要服务器跳闸

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

CCJS是您随时准备好的会议指南。它会立即告诉您哪些会议可用,何时何地,以便您可以在大厅中找到所需的会议,并到达那里。如果您参加过技术会议或酒店,您就会知道wifi通常很糟糕,如果只有在有wifi的情况下才可用,则该应用几乎毫无用处直接访问服务器

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

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

您还将失去导航到相关实体的能力。会话列表显示每个会话的轨迹、时隙和房间。这是在“查找”参考实体中找到的重复信息。您必须展开投影以将此信息包括在会话的“展平”视图中(更胖的负载)或者在客户端进行巧妙操作,手动修补轨道、时隙和房间数据(复杂性)

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

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

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

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

这并不意味着它是每个应用程序的正确选择。它可能不是你的正确选择

例如,如果你总是有一个快速、低延迟的连接,那么#1可能是你最好的选择。我真的不知道

我喜欢从演员到实体的方法,因为这很简单,而且大多数时候效果都很好