Breeze假设EntityType与EntityContainer位于同一名称空间中。 Breeze不应该考虑EntityType值是否是限定类型名称?

时间:2014-04-18 19:08:31

标签: metadata odata breeze

  • 图书馆:BreezeJS 1.4.11客户端库
  • 数据服务适配器:webApiOdata
  • 远程服务:不使用Breeze控制器的OData v3的Web API 2实现

我正在处理来自服务提供商的元数据,该服务提供商更喜欢将EntityContainer保留在与其包含的EntityTypes不同的名称空间中。以下是一些与我们的设置相似的示例:

考虑Breeze的CsdlMetadataParser.parse函数:

var entityTypeName = parseTypeName(entitySet.entityType, schema).typeName;

此函数假定EntityType与EntityContainer具有相同的架构,并且不考虑EntitySet的EntityType属性中提供的命名空间。

前10名的简单Breeze查询"类别"从Northwind服务导致以下错误:

  

错误:无法找到'类型'名称:'类别:#ODataWebV3.Northwind.Model'。请务必先执行查询或调用fetchMetadata。

Breeze不应该考虑EntityType值是否是限定类型名称并使用它而不是假设容器的命名空间?

更新 Breeze还假定给定导航属性的association []始终与nav属性位于同一模式中。尝试在单独的命名空间中导入关联的元数据时,这会导致以下错误:

  

"无法阅读财产'结束' of null"

错误源于Breeze的parseCsdlNavProperty和getAssociation函数:

function parseCsdlNavProperty(entityType, csdlProperty, schema) {
     var association = getAssociation(csdlProperty, schema);

4 个答案:

答案 0 :(得分:0)

在Breeze的CsdlMetadataParser.parse方法中替换此行:

var entityTypeName = parseTypeName(entitySet.entityType, schema).typeName;

有了这个:

var entityTypeName = parseTypeName(entitySet.entityType).typeName;

解决问题并正确考虑EntityType字符串中的命名空间。如果这是正确的策略,我想要来自Ward或其他人的反馈。此外,好奇将模式传递给parseTypeName方法背后的原因,如果删除它会破坏别的东西。

<强>更新 为了支持跨模式的关联,我能够通过将模式数组从CsdlMetadataParser.parse一直传递到getAssociation()来解决这个问题。一旦getAssociation可以访问模式数组,以下两个更新通过删除假设并查看提供的命名空间来解析导入:

function getAssociation(csdlNavProperty, schemas) {
    var assocName = parseTypeName(csdlNavProperty.relationship).shortTypeName;
    var navSchema = __arrayFirst(schemas, function (sch) {
        return sch.namespace === parseTypeName(csdlNavProperty.relationship).namespace;
    });
    var assocs = navSchema.association;
    ...

function parseCsdlNavProperty(entityType, csdlProperty, schema, schemas) {
    var association = getAssociation(csdlProperty, schemas);
    var toEnd = __arrayFirst(association.end, function (assocEnd) {
        return assocEnd.role === csdlProperty.toRole;
    });

    var isScalar = toEnd.multiplicity !== "*";
    var dataType = parseTypeName(toEnd.type).typeName;
    ...

答案 1 :(得分:0)

修改&#34; getQualifiedTypeName&#34;在breeze.debug.js为我做了诀窍......

function getQualifiedTypeName(metadataStore, structTypeName, throwIfNotFound)
{
  structTypeName = (structTypeName || "") + "";
  var shortTypeName = (structTypeName.indexOf(':#') > -1) ?
    structTypeName.substring(0, structTypeName.indexOf(':#')) :
    structTypeName;
  var result = metadataStore._shortNameMap[shortTypeName];
  if (result) return result;
  if (isQualifiedTypeName(structTypeName)) return structTypeName;
  result = metadataStore._shortNameMap[structTypeName];
  ...
  return result;
}

答案 2 :(得分:0)

最新版本的微风是1.5.3,自1.4.11以来已经进行了很多改动。

我会在“修复”CsdlMetadataParser之前尝试一下。

答案 3 :(得分:0)

这仍然是Breeze 1.5.4中的一个问题。我打开了 https://github.com/Breeze/breeze.js/issues/96 为它(似乎是一个错误而不是一个SO问题?)。

我找到的解决方法是修改

if (schema) {

function parseTypeNameWithSchema(entityTypeName, schema)(breeze.debug.js第7327行)中行,以便该函数为:

// schema is only needed for navProperty type name function parseTypeNameWithSchema(entityTypeName, schema) { var result = parseTypeName(entityTypeName); if (schema && !result.namespace) { var ns = getNamespaceFor(result.shortTypeName, schema); if (ns) { result = makeTypeHash(result.shortTypeName, ns); } } return result; }

我认为这是正确的行为,因为如果EntityType名称是完全作用域的,则应使用其名称空间;如果EntityType只是名称,则应使用周围的模式命名空间。