Как создать коллекцию сложного типа в olingo
Я стараюсь следовать нижеприведенному документу olingo, чтобы создать сервис odata.
Но мне не удается создать сущность со свойством, тип которого является List of ComplexType. У любого есть пример этого. Или это просто не поддерживается?
2 ответа
Может быть , ответ Утсава был верным в тот момент, но Odata v4 действительно поддерживает сущность со свойством, тип которого " List of ComplexType".
Доказательство : в этом примере entityType Person имеет свойство AddressInfo, а его тип является коллекцией ComplexType:
<ComplexType Name="Location" OpenType="true">
<Property Name="Address" Type="Edm.String" Nullable="false"/>
<Property Name="City" Type="Microsoft.OData.SampleService.Models.TripPin.City" Nullable="false"/>
</ComplexType>
...
<EntityType Name="Person" OpenType="true">
<Property Name="AddressInfo" Type="Collection(Microsoft.OData.SampleService.Models.TripPin.Location)"/>
...
</EntityType>
Что касается реализации Olingo, в вашем провайдере CSDL вы должны правильно определить сущность вашего сложного типа, а затем определить свойство, которым вы хотите быть коллекцией этого сложного типа. Тогда вы должны правильно обработать результат.
1. Определение метаданных в CSDL-провайдере
В вашем провайдере getSchemas()
Метод, который вы должны объявить ваши сложные типы:
List <CsdlComplexType> complexTypes = new ArrayList<>();
//...initialization of complexTypes list...
schema.setComplexTypes(complexTypes);
В getEntityType()
Метод, которым вы должны создать свое свойство как коллекцию объектов сложного типа:
//...initialization of entityType...
List<CsdlProperty> properties = new ArrayList<>();
FullQualifiedName type;
//...initialization of the type as a complex type...
properties.add(new CsdlProperty().setName("propertyName").setType(type).setCollection(true));
entityType.setProperties(properties);
//...
2. Обработка результата
В реализации вашего процессора вы должны правильно построить свою сущность: например, в readEntityCollection()
метод EntityCollectionProcessor
В реализации у вас должно быть что-то похожее на это:
EntityCollection entities = new EntityCollection();
List<Entity> eList = entities.getEntities();
Entity e = new Entity();
List<Map> data;
//...initialization of complex type's data...
List<ComplexValue> properties = new ArrayList<>();
for (Object complexObject : data) {
ComplexValue complexValue = new ComplexValue();
for (Map.Entry<String, Object> entry : complexObject.entrySet()) {
complexValue.getValue().add(new Property(null, entry.getKey(), ValueType.PRIMITIVE, entry.getValue()));
}
properties.add(complexValue);
}
e.addProperty(new Property(null, "propertyName", ValueType.COLLECTION_COMPLEX, properties););
eList.add(e);
//...serialize and set the result to response
Я столкнулся с аналогичным требованием в моем проекте вчера. Тогда я заметил твой вопрос, который остался без ответа. Я реализовал подход, который работает для меня. Я описываю это ниже. Надеюсь, это поможет.
В двух словах: как я понимаю, так это то, что мы не можем использовать ComplexType для создания объекта в виде списка. Нам нужно использовать свойство навигации.
Постановка задачи: я должен прочитать сущность - EntityA. EntityA относится к EntityB. Отношение ОДИН-НА-МНОГО, т.е. EntityA содержит список EntityB. Типичное представление JSON будет следующим:
EntityA:{
"id":"entityA_1",
"entityBList":[
{//EntityB Element
"id" : "entityB_1",
"description":"value1"
},
{//EntityB Element
"id" : "entityB_2",
"description":"value1"
}
]
}
чтобы прочитать его со стороны клиента, я использую запрос OData с расширением - odata.sv/EntityA(1)?$expand=EntityB
Решение: чтобы включить описанный выше сценарий на стороне сервера, мне пришлось использовать свойства навигации.
Сначала мы создаем две отдельные сущности - EntityA и EntityB. Затем мы определяем отношения
- реализации метода getAssociation и
- в EdmProvider настройка свойств навигации при определении EntityA
- Далее, во время чтения Entity(readEntity), мы предоставляем обратный вызов
метод путем переопределения 'retrieveFeedResult' для заполнения EntityB.
У меня есть работающий POC для этого. Я могу также поделиться этим, если это необходимо. Сейчас у меня мало времени, поэтому просто поделились общим подходом. Надеюсь это поможет.