2013-10-09 49 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; 
}