2013-10-09 48 views
0

我试图懒惰加载微风中的复杂类型,但无法找出一种方法来实现这一点。微风 - 延迟加载复杂类型

我想使用复杂类型而不是导航方式的原因是,我必须使用的服务不像微风那样使用CRUD。我必须将所有子对象(包括标量和非标量)的单个对象发送到负责存储数据(插入/更新/删除)的单一服务方法。

我试图做到这一点与导航属性,但这意味着我必须创建一个实体数组发送到一个API控制器,并在那里重新创建整个对象。这很难,但更重要的是,因为子对象中没有外键(这是我迄今看到的所有示例中的情况),因此再次映射它们是一件痛苦的事情。

复杂的类型,我没有这个问题(或不是我所知道的)。

我要消耗的对象结构是这样的:

1.Parent:产物(类)

1.1Child:包(阵列)

1.2Child:splitLevels(数组)

1.2.1Grandchild:权限(阵列)

1.2.1.1Grandgrandchild:药房(数组)

1.2.2Grandchild:splitLevel(class)

软件包与产品一起加载,这工作得很好。 Howevers,splitLevels不包含在这个数据合同中(因为它需要太多的数据,不会经常咨询)。当请求这些数据时,会在产品中添加一个布尔值来表明它们已经被加载,从那时起它也需要将它们发送到服务器。

当装载产品,这将导致一个问题: 对象不支持属性或方法“的getProperty”

这是由_​​initializeInstance方法在风引起的:

if (initFn) { 
    if (typeof initFn === "string") { 
     initFn = instance[initFn]; 
    } 
    initFn(instance); 
} 
this.complexProperties && this.complexProperties.forEach(function (cp) { 
    var ctInstance = instance.getProperty(cp.name); 
    cp.dataType._initializeInstance(ctInstance); 
}); 

的实例空的,没有属性可以从中获取。

有什么办法可以解决这个问题吗? 有没有办法使用导航属性而不会获取多个实体;这样我就可以送一个对象,而无需使用这样的:

if (product.entityAspect.entityState.isUnchanged()) { 
    product.entityAspect.setModified(); 
} 

// Packages 
var entitiesToSave = product.packages().slice();// copy 

// Split Levels 
if (product.storeSplitLevels) { 
    product.splitLevelsLoaded(true); 
    // TODO: Add split levels to entities to save 
} 

// Product Details 
entitiesToSave.push(product); 

回答

0

没有更多的信息,我不是你的要求完全清楚,但我们正计划增加一个功能,微风API进行了EntityManager即会允许您使用任意数据结构调用任意端点,并将调用结果(如果有)通过JsonResultsAdapter合并回EntityManager。

在此之前,您可以通过绕过EntityManager.saveChanges并直接使用Breeze ajax适配器直接调用您的端点来完成此操作。类似于

var ajaxImpl = breeze.config.getAdapterInstance("ajax"); 
ajaxImpl.ajax({ 
     type: "POST", 
     url: url, 
     dataType: 'json', 
     contentType: "application/json", 
     data: bundle, // arbitrary data to server. 
     success: function (httpResponse) { 
      // perform custom client side code 
     }, 
     error: function (httpResponse) { 

     } 
    }); 
+0

对不起这个,我的问题是: 1.是否有可能延迟加载嵌套复杂类型;是包含复杂类型的数组,其中包含其他复杂类型。我无法得到这个工作(cfr从微风的代码块)。 2.如果没有,有没有办法使用导航属性,而没有在同一级别的所有实体,但传入的数据合同定义它们的方式相同。但你真的用你的评论回答了这个问题。 – Reinout

1

我按照您的建议创建了自定义捆绑软件。

对于具有同样问题的其他开发者,我做了以下内容:

  1. 创建一个自定义解包功能,它提供了相同的功能在微风中解包功能,但扩展它包含导航性能好。

  2. 添加从实体创建保存包的方法。

代码:

function createEntitySaveBundle(entity) { 
    var rawEntity = unwrapInstance(entity); 
    var entities = []; 
    rawEntity.entityAspect = { 
     entityTypeName: entity.entityType.name, 
     defaultResourceName: entity.entityType.defaultResourceName, 
     entityState: entity.entityAspect.entityState.name, 
     autoGeneratedKey: { 
      propertyName: entity.entityType.keyProperties[0].nameOnServer, 
      autoGeneratedKeyType: entity.entityType.autoGeneratedKeyType.name 
     } 
    }; 
    entities.push(rawEntity); 

    return { entities: entities, saveOptions: {} }; 
} 

function unwrapInstance(entity) { 
    var rawObject = {}; 
    var stype = entity.entityType || entity.complexType; 
    var val; 
    var entities; 

    stype.dataProperties.forEach(function (dp) { 
     if (dp.isUnmapped) { 
      val = entity.getProperty(dp.name); 
      val = transformValue(val, dp, false); 
      if (val !== undefined) { 
       rawObject.__unmapped = rawObject.__unmapped || {}; 
       // no name on server for unmapped props 
       rawObject.__unmapped[dp.name] = val; 
      } 
     } else if (dp.isComplexProperty) { 
      if (dp.isScalar) { 
       rawObject[dp.nameOnServer] = unwrapInstance(entity.getProperty(dp.name)); 
      } else { 
       entities = entity.getProperty(dp.name); 
       rawObject[dp.nameOnServer] = entities.map(function (co) { return unwrapInstance(co); }); 
      } 
     } else if (dp.isDataProperty) { 
      val = entity.getProperty(dp.name); 
      val = transformValue(val, dp); 
      if (val !== undefined) { 
       rawObject[dp.nameOnServer] = val; 
      } 
     } 
    }); 

    stype.navigationProperties.forEach(function (np) { 
     if (np.isScalar) { 
      // Doesn't occur with products, enabling this results in an endless loop without checking if the navigation property already exists in the rawObject (recursive..) 
      // rawObject[np.nameOnServer] = unwrapInstance(entity.getProperty(np.name)); 
     } else { 
      entities = entity.getProperty(np.name); 
      rawObject[np.nameOnServer] = entities.map(function (eo) { return unwrapInstance(eo); }); 
     } 
    }); 

    return rawObject; 
} 
function transformValue(val, prop) { 
    if (prop.isUnmapped) return; 
    if (prop.dataType === breeze.DataType.DateTimeOffset) { 
     // The datajs lib tries to treat client dateTimes that are defined as DateTimeOffset on the server differently 
     // from other dateTimes. This fix compensates before the save. 
     val = val && new Date(val.getTime() - (val.getTimezoneOffset() * 60000)); 
    } else if (prop.dataType.quoteJsonOData) { 
     val = val != null ? val.toString() : val; 
    } 
    return val; 
}