Breeze JS:有没有办法从data.results中查询实体

Breeze JS: Is there a way to query entities from data.results?

本文关键字:results data 查询 实体 JS 有没有 Breeze      更新时间:2023-09-26

我有一个Breeze Web api控制器,其方法接受参数并在服务器上执行一些工作,过滤,排序等。在查询成功时,我想对 data.results 进行进一步查询。有没有办法做到这一点?我通过将 data.results 导出/导入到本地管理器并从那里进行投影来获得这项工作。为了在供应商网格控件中使用可观察集合,需要投影。

        var query = datacontext.EntityQuery.from("GetActiveCustomers")
            .withParameters({ organizationID: "1" })
            .toType("Customer")
            .expand("Organization")
            .orderBy('name');
        var queryProjection = query
                .select("customerID, organizationID, name, isActive, organization.name");
        return manager.executeQuery(query)
            .then(querySucceeded)
            .fail(queryFailed);
        function querySucceeded(data) {
            var exportData = manager.exportEntities(data.results);
            var localManager = breeze.EntityManager.importEntities(exportData);
            var resultProjection = localManager.executeQueryLocally(queryProjection); 
    //This is the way I came up with to query data.results (exporting/importing the result entities to a local manager)
    //Is there a better way to do this? Querying directly data.results. Example: data.results.where(...).select("customerID, organizationID...)
            if (collectionObservable) {
                collectionObservable(resultProjection);
            }
            log('Retrieved Data from remote data source',
                data, true);
        }

你采取了一个有趣的方法。通常,投影返回不可缓存的对象,而不是实体。但是您将其转换为Customer(使用 toType 子句(,这意味着您已经创建了缺少数据的 PARTIAL Customer 实体。

我必须希望您知道自己在做什么,并且无意在保留部分更改时保存对这些客户实体的更改,否则可能会发生灾难。

请注意,当您将选定的客户导入"localManager"时,您没有带来他们的相关Organization实体。这意味着诸如 resultProjection[0].organization 之类的表达式将返回 null。这似乎不正确。

我知道您希望保留Customer部分实体的子集,并且没有本地查询可以从缓存中选择该子集,因为选择标准仅在服务器上完全已知。

我想我会以不同的方式处理这种需求。

首先,我将所有这些逻辑埋在DataContext本身中;DataContext的目的是封装数据访问的细节,以便调用者(如ViewModels(不必知道内部。该DataContext是工作单元 (UoW( 模式的一个示例,该模式是一种抽象,有助于将数据访问/操作问题与 ViewModel 问题隔离开来。

然后,我会将其存储在 DataContext (DC( 或 ViewModel (VM( 的命名数组中,具体取决于此子集在应用程序中是狭义还是广泛。

如果只有 VM 实例关心此子集,则 DC 应返回data.results并让 VM 保留它们。

我不明白为什么要重新查询此集合的本地实体管理器,也不明白为什么您的本地查询也应用投影......这会将非实体数据对象返回给调用方。返回(部分(客户实体有什么问题。

您似乎打算进一步过滤客户端上的子集。嘿。。。它是一个JavaScript数组。你可以打电话给stuffArray.filter(filterFunction)

当然,这不会给你类似 Breeze LINQ 的查询语法......但你真的需要吗?为什么需要".select"而不是该集合?

如果这真的是您的需求,那么我想我理解您为什么要将结果转储到单独的 EntityManager 中以供本地使用。在这种情况下,我相信您的查询回调方法中需要更多的代码来将相关的Organization实体导入到该本地 EM 中,以便someCustomer.organization返回一个值。这种方法越来越棘手,这让我感到不舒服,但这是你的应用程序。

如果你继续沿着这条路走下去,我强烈建议你把它封装在DC或某种服务类中。我不希望我的虚拟机知道任何这些恶作剧。

祝你好运。

2013 年 10 月 3 日更新:对未映射属性进行本地缓存查询筛选

睡在上面之后,我有另一个想法给你,在这个用例中消除了你对第二个EM的需求。

可以将未映射的属性添加到客户端Customer实体,并在查询服务器上的"GetActiveCustomers"终结点后使用子集标记设置该属性;在查询回调中设置标记。

然后,您可以编写一个本地查询,该查询筛选标记值,以确保仅考虑该子集中Customer对象。

仅在本地查询中引用标记值。我不知道对标记值进行远程查询过滤是否会失败或干脆忽略该标准。

您不需要单独的本地实体管理器;主管理器中的Customer实体携带服务器端筛选的证据。当然,服务器永远不必处理未映射的属性值。

是的,breeze 本地查询可以针对未映射的属性以及映射的属性。

这是一个小演示。注册一个自定义构造函数,如下所示:

function Customer() { /* Custom constructor ... which you register with the metadataStore*/
    // Add unmapped 'subset' property to be queried locally.
    this.subset = Math.ceil(Math.random() * 3); // simulate values {1..3}
}

稍后在本地查询它。下面是引用和不引用该属性的查询示例:

// All customers in cache
var x = breeze.EntityQuery.from("Customers").using(manager).executeLocally();
// All customers in cache whose unmapped 'subset' property === 1.
var y = breeze.EntityQuery.from("Customers")
        .where("subset", 'eq', 1) // more criteria; knock yourself out
        .using(manager).executeLocally();

我相信你会知道如何在对"GetActiveCustomers"查询的回调中适当地设置 subset 属性。

一旦您查询了一些数据,这些实体就会在本地内存中存储。

您所要做的就是在需要进一步过滤数据时在本地查询。为此,您可以指定管理器在本地查询:

manager.executeQueryLocally(query);

由于从数据库查询是异步完成的,因此必须确保仅当本地内存中存在某些内容时才从本地内存中检索。信守承诺。