I try to follow below document of olingo to create a odata service.
But I fail to create a entity with property whose type is a List of ComplexType. Anyone has an example of it. Or is it just not supported ?
I try to follow below document of olingo to create a odata service.
But I fail to create a entity with property whose type is a List of ComplexType. Anyone has an example of it. Or is it just not supported ?
Maybe Utsav's answer was correct at that point of time, but Odata v4 does support an entity with property whose type is a "List of ComplexType".
Prove:
In this sample entityType Person has property AddressInfo and its type is a collection of 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>
Regarding Olingo implementation, in your CSDL provider you have to properly define your complex type entity, and then define the property, that you want to be a collection of this complex type. Then you have to correctly process the result.
In your provider's getSchemas()
method you have to declare your complex types:
List <CsdlComplexType> complexTypes = new ArrayList<>();
//...initialization of complexTypes list...
schema.setComplexTypes(complexTypes);
In getEntityType()
method you have to create your property as a collection of complex type objects:
//...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);
//...
In your processor's implementation you have to correctly build your entity:
for example, in readEntityCollection()
method of EntityCollectionProcessor
implementation you should have something similar to this:
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
I came across for a similar requirement in my project yesterday. That is when I noticed your question which was unanswered. I have implemented an approach which works for me. I am describing it below. Hopefully, it will be of some help.
In nutshell: How I understand it as is that we cannot use ComplexType for having entity as a list. We need to use navigation property.
Problem Statement : I have to read an entity - EntityA. EntityA is related to EntityB. Relation is ONE-TO-MANY i.e. EntityA contains a list of EntityB. A typical JSON representation would be as follows:
EntityA:{
"id":"entityA_1",
"entityBList":[
{//EntityB Element
"id" : "entityB_1",
"description":"value1"
},
{//EntityB Element
"id" : "entityB_2",
"description":"value1"
}
]
}
to read it from the client side I use a OData query with expand - odata.sv/EntityA(1)?$expand=EntityB
Solution: To enable the above scenario on server side, I had to use navigation properties.
First we create two separate entities - EntityA and EntityB. Then we define the relationship by
I have working POC for this. I can as well share this, if that is needed. Right now I am short of time, so just shared an overall approach. Hope this helps.