我正在尝试基于Query加载实体并允许用户编辑它。实体在没有查询问题的情况下加载,但是它不会加载其相关实体,在加载编辑屏幕时会留下未填充的详细信息。
这是我的代码:
myapp.BrowseCOAMissingHoldingCompanies.VW_ChartOfAccountsWithMissingHoldingCompanies_ItemTap_execute = function (screen) {
var accountName = screen.VW_ChartOfAccountsWithMissingHoldingCompanies.selectedItem.AccountFullName;
return myapp.activeDataWorkspace.Accounting360Data.FindChartOfAccountsMappingByAccountName(accountName)
.execute().then(function (query) {
var coa = query.results[0];
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
};
有趣的是,如果我首先打开该实体类型的浏览屏幕(并没有别的)(它确实检索实体),那么相关实体正确加载并且一切正常,但我无法弄清楚如何制作该级别负载发生在此代码中。
答案 0 :(得分:1)
解决此问题的一种方法(并避免执行后续刷新的额外查询)是使用expand方法包含任何其他导航属性,如下所示:
myapp.BrowseCOAMissingHoldingCompanies.VW_ChartOfAccountsWithMissingHoldingCompanies_ItemTap_execute = function (screen) {
var accountName = screen.VW_ChartOfAccountsWithMissingHoldingCompanies.selectedItem.AccountFullName;
return myapp.activeDataWorkspace.Accounting360Data.FindChartOfAccountsMappingByAccountName(
accountName
).expand(
"RelatedEntity," +
"AnotherRelatedEntity," +
"AnotherRelatedEntity/SubEntity"
).execute().then(function (query) {
var coa = query.results[0];
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
}
由于你没有提到实体导航属性的名称,我在上面的例子中使用了coa.RelatedEntity,coa.AnotherRelatedEntity和coa.AnotherRelatedEntity.SubEntity。
正如LightSwitch的intellisense(msls - ?。?。? - vsdoc.js)所述,此方法'通过使用由OData $ expand系统查询选项定义的表达式包含其他导航属性来扩展结果'并且它接受单个'一个OData扩展表达式(以逗号分隔的导航属性名称列表)'的参数。
强制刷新coa的原因还在于填充导航属性,LightSwitch的刷新方法隐式扩展了所有导航属性(前提是您在调用刷新时未指定navigationPropertyNames参数)。下面显示了LightSwitch刷新方法的内部实现(如果navigationPropertyNames参数为null,则执行隐式扩展行为):
function refresh(navigationPropertyNames) {
var details = this,
properties = details.properties.all(),
i, l = properties.length,
property,
propertyEntry,
query;
if (details.entityState !== _EntityState.unchanged) {
return WinJS.Promise.as();
}
if (!navigationPropertyNames) {
navigationPropertyNames = [];
for (i = 0; i < l; i++) {
property = properties[i];
propertyEntry = property._entry;
if (isReferenceNavigationProperty(propertyEntry) &&
!isVirtualNavigationProperty(propertyEntry)) {
navigationPropertyNames.push(propertyEntry.serviceName);
}
}
}
query = new _DataServiceQuery(
{
_entitySet: details.entitySet
},
details._.__metadata.uri);
if (navigationPropertyNames.length > 0) {
query = query.expand(navigationPropertyNames.join(","));
}
return query.merge(msls.MergeOption.unchangedOnly).execute();
}
但是,如果采用刷新方法,您将执行额外的不必要的查询操作。
答案 1 :(得分:0)
实体框架默认使用延迟加载,因此相关数据将按需加载,但在您的情况下为时已晚,因为实体已经是客户端的那一点。
如果您想要预先加载,请尝试在查询中使用Include
method。
答案 2 :(得分:0)
调用实体细节的刷新似乎是这样做的:
return coa.details.refresh().then(function() {
return myapp.showAddEditChartOfAccountsMapping(coa, {
beforeShown: function (addEditScreen) {
addEditScreen.ChartOfAccountsMapping = coa;
},
afterClosed: function () {
screen.VW_ChartOfAccountsWithMissingHoldingCompanies.refresh();
}
});
});
答案 3 :(得分:0)
您应该使用load方法从Server获取相关数据。目前我们没有办法强制msls加载相关数据。