В прошлом посте было рассказано об ассоциации и навигации. В результате получили несколько вызовов сущностей, происходящих друг за другом. Однако, данный способ накладывает некоторые ограничения и потенциальные потери производительности, т.к. вместо одного RFC вызывается целая цепочка. Также часто нужно данные для передачи на фронт мы получаем одновременно, например как результат работы ФМ. Конечно, можно положить эти данные в буфер и брать необходимое во время вызова соответствующей сущности, звучит не очень рационально.
Стандартный интерфейс позволяет сделать так, чтобы все зависимые сущности заполнялись одновременно.
Не могу придумать какой-то более менее вменяемы пример, поэтому все будет максимально упрощенно.
Допустим необходимо по ключу получить запись таблицы SPFLI и зависимых ей SFLIGHT и SBOOK
Первым делом создадим таблицу сущность SBOOK аналогично созданной ранее SFLIGHT
И связь с сущностью EntitySpfli
Вот какие навигации у нас теперь есть от EntitySpfli
Далее в классе *DPC_EXT необходимо переопределить соответствующий метод GET_EXPANDED_ENTITY или GET_EXPANDED_ENTITYSET. Как определить какой метод нам нужен? Очень просто, все зависит от кардинальности нашей самой первой сущности. В данном примере это 0..1 значит и метод вызовется
GET_EXPANDED_ENTITY.
Обратите внимание, что методы GET_EXPANDED_ENTITY и GET_EXPANDED_ENTITYSET определяются один раз. Т.е. после их определения все вызовы expand будут происходить именно через эти методы, а не вызов отдельных GET_ENTITY или GET_ENTITYSET для соответствующей сущности. Этот момент надо предусмотреть в коде и при необходимости вызвать отдельный метод вручную.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity. *Выходная структура, это один из основных моментов * entitysflightset и entitysbookset должны называться именно так * т.к. это имена соответствующих Navigation Properties в oData * их типы тоже должны соответствовать типам сущностей + учитывать кардинальность * если бы у какой-то из сущностей была кардинальность 1 вместо n * следовало бы использовать тип zcl_zz_test_service_mpc=>t* DATA: BEGIN OF ls_result. INCLUDE TYPE zcl_zz_test_service_mpc=>ts_entityspfli. DATA: entitysflightset TYPE zcl_zz_test_service_mpc=>tt_entitysflight, entitysbookset TYPE zcl_zz_test_service_mpc=>tt_entitysbook, END OF ls_result. CASE iv_entity_name. *Ветка для сущности 'EntitySpfli' WHEN 'EntitySpfli'. DATA lt_result LIKE TABLE OF ls_result. DATA(lv_mandt) = it_key_tab[ name = 'Mandt' ]-value. DATA(lv_carrid) = it_key_tab[ name = 'Carrid' ]-value. DATA(lv_connid) = it_key_tab[ name = 'Connid' ]-value. SELECT SINGLE * FROM spfli INTO CORRESPONDING FIELDS OF ls_result WHERE carrid = lv_carrid AND connid = lv_connid. SELECT * FROM sflight INTO CORRESPONDING FIELDS OF TABLE ls_result-entitysflightset WHERE carrid = lv_carrid AND connid = lv_connid. SELECT carrid connid FROM sbook INTO CORRESPONDING FIELDS OF TABLE ls_result-entitysbookset WHERE carrid = lv_carrid *В таблицу et_expanded_tech_clauses кладем имена обработанных Navigation Properties *Для избежания повторного вызова методов для их обработки AND connid = lv_connid. APPEND 'ENTITYSFLIGHTSET' TO et_expanded_tech_clauses. APPEND 'ENTITYSBOOKSET' TO et_expanded_tech_clauses. copy_data_to_ref( EXPORTING is_data = ls_result CHANGING cr_data = er_entity ). *если вдруг мы обрабатываем сущность 'EntitySflightSet' используем вызов метода *get_entity WHEN 'EntitySflightSet'. * Call the entity set generated method DATA entitysflightset_get_entity TYPE zcl_zz_test_service_mpc=>ts_entitysflight. entitysflightset_get_entity( EXPORTING iv_entity_name = iv_entity_name iv_entity_set_name = iv_entity_set_name iv_source_name = iv_source_name it_key_tab = it_key_tab it_navigation_path = it_navigation_path io_tech_request_context = io_tech_request_context IMPORTING er_entity = entitysflightset_get_entity es_response_context = es_response_context ). IF entitysflightset_get_entity IS NOT INITIAL. * Send specific entity data to the caller interface copy_data_to_ref( EXPORTING is_data = entitysflightset_get_entity CHANGING cr_data = er_entity ). ENDIF. ENDCASE. ENDMETHOD. |
Примечание:
1. Структура для результата должна точно соответствовать типам сущностей и их кардинальности. Если мы вызываем GET_EXPANDED_ENTITYSET то соответственно выходной будет уже таблица, а не структура.
2. Необходимо заполнять выходную таблицу et_expanded_tech_clauses наименованиями обработанных сущностей. Иначе expand будет вызван еще и еще.
Строка вызова:
/sap/opu/odata/sap/ZZ_TEST_
В результате получили все связанные данные в одном вызове
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
{ "d" : { "__metadata" : { "id" : "ZZ_TEST_SERVICE_SRV/EntitySpfliSet(Mandt='100',Carrid='AA',Connid='0017')", "uri" : "ZZ_TEST_SERVICE_SRV/EntitySpfliSet(Mandt='100',Carrid='AA',Connid='0017')", "type" : "ZZ_TEST_SERVICE_SRV.EntitySpfli" }, "Mandt" : "100", "Carrid" : "AA", "Connid" : "0017", "Countryfr" : "US", "Cityfrom" : "NEW YORK", "Airpfrom" : "JFK", "Countryto" : "US", "Cityto" : "SAN FRANCISCO", "Airpto" : "SFO", "Fltime" : "361", "Distance" : "2572.000", "Distid" : "МИЛ", "Fltype" : "", "Period" : 0, "EntitySflightSet" : { "results" : [ { "__metadata" : { "id" : "/EntitySflightSet(Mandt='100',Carrid='AA',Connid='0017')", "uri" : "/EntitySflightSet(Mandt='100',Carrid='AA',Connid='0017')", "type" : "ZZ_TEST_SERVICE_SRV.EntitySflight" }, "Mandt" : "100", "Carrid" : "AA", "Connid" : "0017", "Fldate" : "\/Date(1507766400000)\/", "Price" : "422.94", "Currency" : "USD", "Planetype" : "747-400", "EntitySpfliNav" : { "__deferred" : { "uri" : "" } }, "EntitySbookSet" : { "__deferred" : { "uri" : "" } } }, { "__metadata" : { "id" : "/ZZ_TEST_SERVICE_SRV/EntitySflightSet(Mandt='100',Carrid='AA',Connid='0017')", "uri" : "ZZ_TEST_SERVICE_SRV/EntitySflightSet(Mandt='100',Carrid='AA',Connid='0017')", "type" : "ZZ_TEST_SERVICE_SRV.EntitySflight" }, "Mandt" : "100", "Carrid" : "AA", "Connid" : "0017", "Fldate" : "\/Date(1510531200000)\/", "Price" : "422.94", "Currency" : "USD", "Planetype" : "747-400", "EntitySpfliNav" : { "__deferred" : { "uri" : "" } }, "EntitySbookSet" : { "__deferred" : { "uri" : "" } } } ] }, "SpgliToSflightTestCopy" : { "__deferred" : { "uri" : "" } }, "SpgliToSflightTest" : { "__deferred" : { "uri" : "" } }, "EntitySbookSet" : { "results" : [ { "__metadata" : { "id" : "ata/sap/ZZ_TEST_SERVICE_SRV/EntitySbookSet(Mandt='',Carrid='AA',Connid='0017')", "uri" : "sap/ZZ_TEST_SERVICE_SRV/EntitySbookSet(Mandt='',Carrid='AA',Connid='0017')", "type" : "ZZ_TEST_SERVICE_SRV.EntitySbook" }, "Mandt" : "", "Carrid" : "AA", "Connid" : "0017", "Counter" : "00000000", "Agencynum" : "00000000", "Cancelled" : "", "Reserved" : "" }, { "__metadata" : { "id" : "ZZ_TEST_SERVICE_SRV/EntitySbookSet(Mandt='',Carrid='AA',Connid='0017')", "uri" : "odata/sap/ZZ_TEST_SERVICE_SRV/EntitySbookSet(Mandt='',Carrid='AA',Connid='0017')", "type" : "ZZ_TEST_SERVICE_SRV.EntitySbook" }, "Mandt" : "", "Carrid" : "AA", "Connid" : "0017", "Counter" : "00000000", "Agencynum" : "00000000", "Cancelled" : "", "Reserved" : "" } ] } } } |