3

我尝试按照下面的 olingo 文档来创建 odata 服务。

注释处理器

但是我无法创建一个具有类型为 ComplexType 列表的属性的实体。任何人都有它的例子。还是只是不支持?

4

2 回答 2

6

也许Utsav 的回答在那个时候是正确的,但 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
于 2016-11-29T13:13:19.763 回答
2

我昨天在我的项目中遇到了类似的要求。那是我注意到你的问题没有得到回答的时候。我已经实施了一种适合我的方法。我在下面描述它。希望它会有所帮助。

简而言之:我的理解是我们不能使用 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。然后我们定义关系

    1. 实现 getAssociation 方法和
    2. 在定义 EntityA 时设置导航属性的 EdmProvider
  • 接下来,在读取 Entity(readEntity) 时,我们
    通过覆盖 'retrieveFeedResult' 来提供回调方法来填充 EntityB。

我有为此工作的 POC。如果需要,我也可以分享这个。现在我的时间很短,所以只是分享了一个整体方法。希望这可以帮助。

于 2015-04-10T10:39:35.650 回答