Breeze 从EntityQuery获取普通JavaScript对象(对于大型结果集)?

Breeze 从EntityQuery获取普通JavaScript对象(对于大型结果集)?,breeze,Breeze,Breeze非常出色,但是我们遇到了内存问题,结果集很大。我对我想要实现的目标有一个想法,并且会重视关于最佳方法的任何想法 对于特殊(大型)结果集,我希望Breeze能够像普通一样对服务器服务执行查询,但不会将这些结果转换为实体——而是去掉额外的“Breeze”JSON,并为我提供一个JavaScript对象的简单列表(理想情况下,属性大小写会根据客户机进行更改) 然后,我可以将这些结果放入ObservableArray,并使用Knockout绑定它们——但不需要观察或跟踪每个属性的开销 当用

Breeze非常出色,但是我们遇到了内存问题,结果集很大。我对我想要实现的目标有一个想法,并且会重视关于最佳方法的任何想法

  • 对于特殊(大型)结果集,我希望Breeze能够像普通一样对服务器服务执行查询,但不会将这些结果转换为实体——而是去掉额外的“Breeze”JSON,并为我提供一个JavaScript对象的简单列表(理想情况下,属性大小写会根据客户机进行更改)

  • 然后,我可以将这些结果放入ObservableArray,并使用Knockout绑定它们——但不需要观察或跟踪每个属性的开销

  • 当用户表示要编辑记录时,我可以创建一个适当的Breeze实体,并将其拼接到ObservalArray中,以代替普通Javascript对象。只要属性名完全匹配,那么淘汰绑定就不会更明智

  • 然后,Breeze可以跟踪更改,并为实际编辑的少数记录提供正常保存

我希望保留Breeze的一些价值,但避免这些大型结果集的开销。具体来说,如果可能的话,我希望避免创建自定义(非Breeze)服务器端控制器方法

有谁能建议最好的地方,打破微风,试图实现这一点?(或更好的方法)


感谢您的评论。

基本上,Breeze只会为任何具有元数据中描述的实体类型的json创建“可观察对象”。当breeze解析任何查询的传入结果时,它会尝试“识别”json负载中返回的任何entityTypes,如果不能识别,则只返回原始形式的json对象。此解析由“默认”JsonResultsAdapter执行

这意味着如果你不告诉Breeze你的大结果集中的“entityTypes”,那么你就会得到你想要的结果。Breeze在对服务器的初始元数据调用期间获取这些entityType“定义”。对于涉及实体框架的模型,将为模型中描述的任何类型自动提供这些类型。这意味着您创建的任何DTO都不会有entityTypes,除非您为它们显式提供了元数据。因此,一种选择是简单地将大型结果集作为DTO返回

另一种可能更好的选择是,如果这些大型结果集确实包含breeze确实知道的entityTypes,但您只想在特定查询中忽略它们。在这种情况下,最好的选择是为这些查询编写一个定制的JsonResultsAdapter,该查询不返回entityType。大概是这样的:

   var customJsonResultsAdapter = new breeze.JsonResultsAdapter({
        name: "ignoreEntityTypeAdapter",

        visitNode: function (node, mappingContext, nodeContext) {
            return {  };
        }
    });

    var query = EntityQuery.from("QueryThatResultsLargeResultSet")
         .where(...)
         .using(customJsonResultsAdapter);

希望这足够清楚

基本上,Breeze只会为任何具有元数据中描述的实体类型的json创建“可观察对象”。当breeze解析任何查询的传入结果时,它会尝试“识别”json负载中返回的任何entityTypes,如果不能识别,则只返回原始形式的json对象。此解析由“默认”JsonResultsAdapter执行

这意味着如果你不告诉Breeze你的大结果集中的“entityTypes”,那么你就会得到你想要的结果。Breeze在对服务器的初始元数据调用期间获取这些entityType“定义”。对于涉及实体框架的模型,将为模型中描述的任何类型自动提供这些类型。这意味着您创建的任何DTO都不会有entityTypes,除非您为它们显式提供了元数据。因此,一种选择是简单地将大型结果集作为DTO返回

另一种可能更好的选择是,如果这些大型结果集确实包含breeze确实知道的entityTypes,但您只想在特定查询中忽略它们。在这种情况下,最好的选择是为这些查询编写一个定制的JsonResultsAdapter,该查询不返回entityType。大概是这样的:

   var customJsonResultsAdapter = new breeze.JsonResultsAdapter({
        name: "ignoreEntityTypeAdapter",

        visitNode: function (node, mappingContext, nodeContext) {
            return {  };
        }
    });

    var query = EntityQuery.from("QueryThatResultsLargeResultSet")
         .where(...)
         .using(customJsonResultsAdapter);

希望这足够清楚

根据上面的评论,当使用
customJsonResultsAdapter
方法时,我们错过了让Breeze连接所有导航属性等的机会。本质上,我们想要微风的好处,而不需要将所有实体属性转换为可忽略的可观察对象(直到我们需要它们)

编辑:由于以前的自定义模型库方法中存在错误,答案已更改为使用两个实用程序函数

作为替代解决方案,我们改为使用内置的Breeze
backingStore
modelLibrary适配器,并添加了两个函数,以便在需要时可以观察到单个实体。其后果是:

  • 这是一种“精简”方法,非常适合于只读数据
  • Breeze截取对这些属性的更改,并像正常情况一样跟踪它们
  • 我们仍然可以使用Knockout绑定lite实体,但是,由于默认情况下属性是不可见的,因此如果属性值发生更改,网页将不会得到更新
当用户确实想要编辑实体时,我们会执行以下操作

    function startEditing(entity, uiElement) {
        if (!breeze.utils.isObservable(entity)) {
            breeze.utils.makeObservable(entity);
            ko.applyBindings(entity, uiElement);
        }
以下是几个重要注意事项:

  • 在使实体可见之后,我们需要重新执行applyBindings,以便属性更改触发Knockout以更新UI
  • 我们的makeObservable函数使用括号,因此标记绑定中不需要括号(尽管仅限于IE9+)

我在下面包含了自定义函数的代码。在加载上述Knockout、Breeze和Steve的插件后,需要包含此代码

// Add a function to make an individual Breeze entity observable.
// Requires the Knockout ES5 plugin from http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax/
// Note: Breeze must be configured to use it's built in backingStore adapter: 
//     breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);

(function () {

    var utils = breeze.utils = breeze.utils || {};

    utils.makeObservable = function (entity) {
        var bs = entity && entity._backingStore;
        if (!bs) {
            throw new Error("Only entities provided by the backingStore adapter can be made observable");
        }
        ko.track(bs);
    };

    utils.isObservable = function (entity) {
        var result = false,
            bs = entity && entity._backingStore;
        if (bs) {
            var propNames = Object.getOwnPropertyNames(bs);
            if (propNames.length > 0) {
                result = !!ko.getObservable(bs, propNames[0]);
            }
        }
        return result;
    };

})();

根据上面的评论,当使用
customJsonResultsAdapter
方法时,我们错过了让Breeze连接所有导航属性等的机会。本质上我们