Breeze 从EntityQuery获取普通JavaScript对象(对于大型结果集)?
Breeze非常出色,但是我们遇到了内存问题,结果集很大。我对我想要实现的目标有一个想法,并且会重视关于最佳方法的任何想法Breeze 从EntityQuery获取普通JavaScript对象(对于大型结果集)?,breeze,Breeze,Breeze非常出色,但是我们遇到了内存问题,结果集很大。我对我想要实现的目标有一个想法,并且会重视关于最佳方法的任何想法 对于特殊(大型)结果集,我希望Breeze能够像普通一样对服务器服务执行查询,但不会将这些结果转换为实体——而是去掉额外的“Breeze”JSON,并为我提供一个JavaScript对象的简单列表(理想情况下,属性大小写会根据客户机进行更改) 然后,我可以将这些结果放入ObservableArray,并使用Knockout绑定它们——但不需要观察或跟踪每个属性的开销 当用
- 对于特殊(大型)结果集,我希望Breeze能够像普通一样对服务器服务执行查询,但不会将这些结果转换为实体——而是去掉额外的“Breeze”JSON,并为我提供一个JavaScript对象的简单列表(理想情况下,属性大小写会根据客户机进行更改)
- 然后,我可以将这些结果放入ObservableArray,并使用Knockout绑定它们——但不需要观察或跟踪每个属性的开销
- 当用户表示要编辑记录时,我可以创建一个适当的Breeze实体,并将其拼接到ObservalArray中,以代替普通Javascript对象。只要属性名完全匹配,那么淘汰绑定就不会更明智
- 然后,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连接所有导航属性等的机会。本质上,我们想要微风的好处,而不需要将所有实体属性转换为可忽略的可观察对象(直到我们需要它们)
编辑:由于以前的自定义模型库方法中存在错误,答案已更改为使用两个实用程序函数
作为替代解决方案,我们改为使用内置的BreezebackingStore
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连接所有导航属性等的机会。本质上我们