簡體   English   中英

在 BreezeJS 中讀取 odata 鏈接

[英]Read odata link in BreezeJS

我正在嘗試讓 BreezeJS 庫與 SAP OData 服務一起工作。 這適用於讀取實體,但我無法解析鏈接的對象。

我的 EntityType 是一個 OrgObject。

<EntityType Name="OrgObject" sap:content-version="1">
  <!-- ... -->
  <NavigationProperty Name="Children" Relationship="ZGW_ORGSTRUCTURE.OrgObject_To_Children" FromRole="FromRole_OrgObject_To_Children" ToRole="ToRole_OrgObject_To_Children"/>
</EntityType>

我有一個鏈接來解析所有鏈接的 OrgObjects(鏈接名為 Children)。

<Association Name="OrgObject_To_Children" sap:content-version="1">
  <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="1" Role="FromRole_OrgObject_To_Children"/>
  <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="*" Role="ToRole_OrgObject_To_Children"/>
</Association>

所以,這個微風查詢正在工作:

var query = new breeze.EntityQuery().from("OrgObjects");
manager.executeQuery(query).then(function(data) {
  data.results.forEach(function(item) {
    console.log(item);
  });
}).fail(/*...*/);

我如何從這個對象中調用“孩子”?

嘗試 1:

var query = new breeze.EntityQuery().from("OrgObjects");
manager.executeQuery(query).then(function(data) {
  data.results.forEach(function(item) {
    console.log(item);
    // ...
    var Children = item.Children();
    // ...
  });
}).fail(/*...*/);

這會導致錯誤:

message: "Object [object Object] has no method 'children'"

嘗試 2:

var query = new breeze.EntityQuery().from("OrgObjects");
manager.executeQuery(query).then(function(data) {
  data.results.forEach(function(item) {
    console.log(item);
    // ...
    item.entityAspect.loadNavigationProperty("Children").then(function(data) {
      console.log(data.results);
      data.results.forEach(function(item) {
        console.log(item);
      });
    }).fail(function(e) {
      console.log(e);
    });
    // ...
  });
}).fail(/*...*/);

這會導致錯誤:

“propertyOrExpr”參數必須是“字符串”

嘗試 3:

var query = new breeze.EntityQuery().from("OrgObjects").expand("Children");
manager.executeQuery(query).then(function(data) {
  data.results.forEach(function(item) {
    console.log(item);
    // ...
    console.log(item.Children);
    console.log( item.Children.length );
    // ...
  });
}).fail(/*...*/);

結果: item.Children是一個對象。 但是item.Children.length = 0 當我檢查 http 響應時,子項是從服務器獲取的,但在item.Children對象中不可用。

控制台輸出:

Finance Department
[parentEntity: Object, navigationProperty: ctor, arrayChanged: ctor, _addsInProcess: Array[0], push: function…]
    _addsInProcess: Array[0]
    _getEventParent: function () {
    _getPendingPubs: function () {
    arrayChanged: ctor
    length: 0
    load: function (callback, errorCallback) {
    navigationProperty: ctor
    parentEntity: Object
    pop: function () {
    push: function () {
    shift: function () {
    splice: function () {
    unshift: function () {
    __proto__: Array[0]
0

誰能幫幫我? 我的 OData 服務中是否缺少某些內容?

問題“解決了”。

僅當定義了逆屬性 (n->1) 時,才能使用微風中的 1->n 關系。 據我所知,在 SAP Gateway 中不可能定義反向關系。 為了測試它,我創建了 2 個關系:

<Association Name="OrgObject_To_Children" sap:content-version="1">
    <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="1" Role="FromRole_OrgObject_To_Children"/>
    <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="*" Role="ToRole_OrgObject_To_Children"/>
</Association>
<Association Name="OrgObject_To_Children_inverse" sap:content-version="1">
    <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="*" Role="FromRole_OrgObject_To_Children_inverse"/>
    <End Type="ZGW_ORGSTRUCTURE.OrgObject" Multiplicity="1" Role="ToRole_OrgObject_To_Children_inverse"/>
</Association>

然后我在微風中改變了這個

function updateCrossEntityRelationship(np) {
    var metadataStore = np.parentType.metadataStore;
    var incompleteTypeMap = metadataStore._incompleteTypeMap;

    // ok to not find it yet
    var targetEntityType = metadataStore._getEntityType(np.entityTypeName, true);
    if (targetEntityType) {
        np.entityType = targetEntityType;
    }

    var assocMap = incompleteTypeMap[np.entityTypeName];
    if (!assocMap) {
        addToIncompleteMap(incompleteTypeMap, np);
    } else {
        var inverse = assocMap[np.associationName];

        /* enable inverse relationship for SAP GATEWAY */
        // search for inverse links
        if( !inverse ){
            var associationName = "";
            if(np.associationName.indexOf("_inverse") > 0){
                associationName = np.associationName.replace("_inverse", "");
            }else{
                 associationName = np.associationName + "_inverse";
            }
            inverse = assocMap[associationName];
        }
        /* end enable inverse relationship for SAP GATEWAY */

        if (inverse) {
            removeFromIncompleteMap(incompleteTypeMap, np, inverse);
        } else {
            addToIncompleteMap(incompleteTypeMap, np);
        }
    }
};

但這並不能解決所有問題,我還必須更改另一件事才能使其正常工作。 不知道這是bug還是和SAP Gateway有關。

function mergeRelatedEntitiesCore(rawEntity, navigationProperty, parseContext) {
    var relatedRawEntities = rawEntity[navigationProperty.nameOnServer];
    if (!relatedRawEntities) return null;

    // needed if what is returned is not an array and we expect one - this happens with __deferred in OData.
    /* original code 
    if (!Array.isArray(relatedRawEntities)) return null;

    var relatedEntities = relatedRawEntities.map(function(relatedRawEntity) {
        return visitAndMerge(relatedRawEntity, parseContext, { nodeType: "navPropItem", navigationProperty: navigationProperty });
    });

    return relatedEntities;
    end original code */

    if (!Array.isArray(relatedRawEntities.results)) 
        return null;

    relatedRawEntities.results = relatedRawEntities.results.map(function(relatedRawEntity) {
        return visitAndMerge(relatedRawEntity, parseContext, { nodeType: "navPropItem", navigationProperty: navigationProperty });
    });

    return relatedRawEntities.results;

}

我只對讀取操作進行了測試。 稍后我將檢查更新操作。

kr, 約阿希姆

免責聲明:我對 Breeze 不是很熟悉,但我猜測可能會發生什么。

關於導航屬性的 Breeze文檔中,它說它不會延遲加載導航屬性。 因此,如果item.Children()數據在本地尚未完全可用,則它不會出去獲取數據。 您需要明確請求將 Children 數據與負載的其余部分內聯檢索,以便在本地獲得此信息。 通常在 OData 中,這是通過請求 URL 中的$expand查詢參數完成的。 在 Breeze 中(根據我鏈接的文檔),它是通過.expand()方法完成的,如下所示:

var query = new breeze.EntityQuery()
              .from("OrgObjects")
              .expand("Children");

@Jowa - 感謝您為將 SAP 和 BreezeJS 結合在一起所做的努力。

您發現expand這是急切加載父OrgObject的子OrgObject

您可以通過loadNavigationProperty按需加載它們......當導航屬性正常工作時......盡管對每個查詢結果一一執行會非常低效。 這種情況需要expand

顯然 Breeze 正在努力處理您的導航屬性,因為它無法識別支持該關系的子實體中的外鍵。

您不必為 1..m 關系的雙方定義導航屬性。 最常被忽略的一側是 1->N 側(父-> 子)屬性。 例如,我們大多數人會省略Gender.Person因為我們不想要集合male.Persons

在您的情況下,如果我理解正確,您認為1->N ( OrgObject.Children ) 已定義但未定義 N->1 導航 ( Child.OrgObject )。 嗯,這也應該有效!

但無論如何,要使導航屬性在任一方向上工作,元數據都必須標識子實體類型中的外鍵 (FK) 屬性。

出於某種原因,微風似乎沒有得到這些信息。

破解 BreezeJS 本身......雖然很聰明......應該沒有必要。

我們願意幫忙。 我們需要以下信息:

  • 服務器上的Child類定義...突出顯示其OrgObject FK 屬性
  • 來自metadataStore對象的OrgObjectChild相關元metadataStore
  • 來自網絡上的元數據文件的OrgObjectChild相關的 JSON

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM