Breeze JS:有没有办法从data.results查询实体? [英] Breeze JS: Is there a way to query entities from data.results?

查看:103
本文介绍了Breeze JS:有没有办法从data.results查询实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a Breeze web api controller, with methods that accept parameters and do some work, filtering, sorting, etc, on the server. On the querySucceeded, I'd like to do further querying to data.results. Is there a way to accomplish this? I got this working by exporting/importing data.results to a local manager, and do the projection from there. The projection is needed in order to use the observable collection in a vendor grid control.

        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 实体

You've taken an interesting approach. Normally a projection returns uncacheable objects, not entities. But you casted this to Customer (with the toType clause) which means you've created PARTIAL Customer entities with missing data.

我必须希望您知道自己在做什么,并且无意在这些客户实体保持零散状态的同时保存更改,否则可能会造成灾难。

I must hope you know what you are doing and have no intention of saving changes to these customer entities while they remain partial else calamity may ensue.

请注意,当您将所选客户导入 localManager时,您并没有带来其相关的 Organization 实体。诸如 resultProjection [0] .organization 之类的表达式将返回null。

Note that when you imported the selected Customers to the "localManager" you did not bring along their related Organization entities. That means an expression such as resultProjection[0].organization will return null. That doesn't seem correct.

我知道您想保留 Customer 部分实体的子集,并且在那里不是可以从缓存中选择该子集的 local 查询,因为选择条件仅在服务器上完全已知。

I understand that you want to hold on to a subset of the Customer partial entities and that there is no local query that could select that subset from cache because the selection criteria are only fully known on the server.

我认为我会以不同的方式处理此需求。

I think I would handle this need differently.

首先,我将所有这些逻辑都埋在 DataContext 本身中; DataContext 的目的是封装数据访问的详细信息,以便调用者(例如ViewModels)不必了解内部信息。 DataContext 是UnitOfWork(UoW)模式的一个示例,该抽象有助于将数据访问/操作问题与ViewModel问题分离开。

First, I would bury all of this logic inside the DataContext itself; the purpose of a DataContext is to encapsulate the details of data access so that callers (such as ViewModels) don't have to know internals. The DataContext is an example of the UnitOfWork (UoW) pattern, an abstraction that helps isolate the data access/manipulation concerns from ViewModel concerns.

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

Then I would store it either in a named array of the DataContext (DC) or of the ViewModel (VM), depending upon whether this subset was of narrow or broad interest in the application.

如果仅VM实例关心该子集,则DC应该返回 data.results 并让VM握住它们。

If only the VM instance cares about this subset, then the DC should return the data.results and let the VM hold them.

我不明白为什么您要为此集合重新查询本地EntityManager,也为什么您的本地查询还要应用投影...实体数据对象给调用者。返回(部分)Customer实体有什么问题。

I do not understand why you are re-querying a local EntityManager for this set nor for why your local query is ALSO appling a projection ... which would return non-entity data objects to the caller. What is wrong with returning the (partial) Customer entities.

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

It seems you intend to further filter the subset on the client. Hey ... it's a JavaScript array. You can call stuffArray.filter(filterFunction).

确保不会像Breeze LINQ那样提供查询语法。 。但是您真的需要吗?为什么需要 .select

Sure that doesn't give you the Breeze LINQ-like query syntax ... but do you really need that? Why do you need ".select" over that set?

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

If that REALLY is your need, then I guess I understand why you're dumping the results into a separate EntityManager for local use. In that case, I believe you'll need more code in your query callback method to import the related Organization entities into that local EM so that someCustomer.organization returns a value. The ever-increasing trickiness of this approach makes me uncomfortable but it is your application.

如果您继续走这条路,我强烈建议您将其封装在DC或某种形式中服务等级。我不想让我的VM知道这些恶作剧。

If you continue down this road, I strongly encourage you to encapsulate it either in the DC or in some kind of service class. I wouldn't want my VMs to know about any of these shenanigans.

运气最好。

睡觉之后,我为您提供了另一个想法,那就是消除了您在此用例中第二个EM的需求。

After sleeping on it, I have another idea for you that eliminates your need for a second EM in this use case.

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

You can add an unmapped property to the client-side Customer entity and set that property with a subset marker after querying the "GetActiveCustomers" endpoint on the server; you'd set the marker in the query callback.

然后,您可以组成一个对标记值进行过滤的本地查询,以确保仅考虑 Customer

Then you can compose a local query that filters on the marker value to ensure you only consider Customer objects from that subset.


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

Reference the marker value only in local queries. I don't know if a remote query filtering on the marker value will fail or simply ignore that criterion.

您不需要单独的本地EntityManager ;主经理中的 Customer 实体带有服务器端过滤的证据。当然,服务器将永远不必处理您未映射的属性值。

You won't need a separate local EntityManager; the Customer entities in your main manager carry the evidence of the server-side filtering. Of course the server will never have to deal with your unmapped property value.

是的,轻而易举的本地查询可以将未映射的属性以及映射的属性作为目标。

Yes, a breeze local query can target unmapped properties as well as mapped properties.

这是一个小示范。注册这样的自定义构造函数:

Here's a small demonstration. Register a custom constructor like this:

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}
}

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

Later you query it locally. Here are examples of queries that do and do not reference that property:

// 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的回调中查询。

I trust you'll know how to set the subset property appropriately in your callback to our "GetActiveCustomers" query.

HTH

这篇关于Breeze JS:有没有办法从data.results查询实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆