我们可以在olingo odata中创建多达3段的导航属性吗

我们可以在olingo odata中创建多达3段的导航属性吗,odata,olingo,Odata,Olingo,我需要在URI中发送3个实体集 e、 例如,{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3 我已经浏览了olingo git repo,只能找到2个段(对于3个段,未实现异常被抛出) 我想了解URL({serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3)是否有效 从OData Sepcifiion的角度来看,使用的Olingo版本是4.5,拥有3级甚至n级的“导航属性”非常好,URL的第一段是实体或

我需要在URI中发送3个实体集

e、 例如,
{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3

我已经浏览了olingo git repo,只能找到2个段(对于3个段,
未实现异常
被抛出)

我想了解URL(
{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3
)是否有效


从OData Sepcifiion的角度来看,使用的Olingo版本是4.5,拥有3级甚至n级的“导航属性”非常好,URL的第一段是实体或实体集,然后您必须创建导航属性,这些属性绑定到(读取返回)和实体集或实体

您得到
未实现异常的原因是,如果您通读
readEntityCollection
的代码,您将发现以下部分

if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
在这里,它会检查段是否是第三部分,并将其视为导航属性,但如果您更深入一层,它只是有一个else条件,它会抛出异常

为了达到你的目的,你必须在你的代码中实现这个逻辑,以达到更深的层次

下面是完整的代码供参考

public void readEntityCollection(ODataRequest请求、ODataResponse响应、UriInfo UriInfo、ContentType响应格式) 抛出ODataApplicationException、SerializerException{

EdmEntitySet responseEdmEntitySet = null; // for building ContextURL
EntityCollection responseEntityCollection = null; // for the response body

// 1st retrieve the requested EntitySet from the uriInfo
List<UriResource> resourceParts = uriInfo.getUriResourceParts();
int segmentCount = resourceParts.size();

UriResource uriResource = resourceParts.get(0); // the first segment is the EntitySet
if (! (uriResource instanceof UriResourceEntitySet)) {
    throw new ODataApplicationException("Only EntitySet is supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}

UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource;
EdmEntitySet startEdmEntitySet = uriResourceEntitySet.getEntitySet();

if(segmentCount == 1){ // this is the case for: DemoService/DemoService.svc/Categories
    responseEdmEntitySet = startEdmEntitySet; // first (and only) entitySet

    // 2nd: fetch the data from backend for this requested EntitySetName
    responseEntityCollection = storage.readEntitySetData(startEdmEntitySet);
}else if (segmentCount == 2){ //navigation: e.g. DemoService.svc/Categories(3)/Products
    UriResource lastSegment = resourceParts.get(1); // don't support more complex URIs
    if(lastSegment instanceof UriResourceNavigation){
        UriResourceNavigation uriResourceNavigation = (UriResourceNavigation)lastSegment;
        EdmNavigationProperty edmNavigationProperty = uriResourceNavigation.getProperty();
        EdmEntityType targetEntityType = edmNavigationProperty.getType();
        responseEdmEntitySet = Util.getNavigationTargetEntitySet(startEdmEntitySet, edmNavigationProperty);

        // 2nd: fetch the data from backend
        // first fetch the entity where the first segment of the URI points to
        // e.g. Categories(3)/Products first find the single entity: Category(3)
        List<UriParameter> keyPredicates = uriResourceEntitySet.getKeyPredicates();
        Entity sourceEntity = storage.readEntityData(startEdmEntitySet, keyPredicates);
        // error handling for e.g.  DemoService.svc/Categories(99)/Products
        if(sourceEntity == null) {
            throw new ODataApplicationException("Entity not found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
        }
        // then fetch the entity collection where the entity navigates to
        responseEntityCollection = storage.getRelatedEntityCollection(sourceEntity, targetEntityType);
    }
}else{ // this would be the case for e.g. Products(1)/Category/Products
    throw new ODataApplicationException("Not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
    // 3rd: create and configure a serializer
    ContextURL contextUrl = ContextURL.with().entitySet(responseEdmEntitySet).build();
    final String id = request.getRawBaseUri() + "/" + responseEdmEntitySet.getName();
    EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with().contextURL(contextUrl).id(id).build();
    EdmEntityType edmEntityType = responseEdmEntitySet.getEntityType();

    ODataSerializer serializer = odata.createSerializer(responseFormat);
    SerializerResult serializerResult = serializer.entityCollection(this.srvMetadata, edmEntityType, responseEntityCollection, opts);

    // 4th: configure the response object: set the body, headers and status code
    response.setContent(serializerResult.getContent());
    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
    response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString());   
}
EdmEntitySet responseEdmEntitySet=null;//用于构建上下文
EntityCollection responseEntityCollection=null;//用于响应正文
//首先从uriInfo中检索请求的EntitySet
List resourceParts=uriInfo.getUriResourceParts();
int segmentCount=resourceParts.size();
UriResource=resourceParts.get(0);//第一段是EntitySet
if(!(UriResourceInstanceof UriResourceEntitySet)){
抛出新的ODataApplicationException(“仅支持EntitySet”,HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
UriResourceEntitySet UriResourceEntitySet=(UriResourceEntitySet)uriResource;
EdmEntitySet startEdmEntitySet=uriResourceEntitySet.getEntitySet();
如果(segmentCount==1){//,则以下情况适用:DemoService/DemoService.svc/Categories
responseEdmEntitySet=startEdmEntitySet;//第一个(也是唯一一个)entitySet
//第二:从后端获取此请求的EntitySetName的数据
responseEntityCollection=storage.readEntitySetData(startEdmEntitySet);
}如果(segmentCount==2){//导航:例如DemoService.svc/Categories(3)/Products
UriResource lastSegment=resourceParts.get(1);//不支持更复杂的URI
if(UriResourceNavigation的最后一段实例){
UriResourceNavigation UriResourceNavigation=(UriResourceNavigation)lastSegment;
EdmNavigationProperty EdmNavigationProperty=uriResourceNavigation.getProperty();
EdmEntityType targetEntityType=edmNavigationProperty.getType();
responseEdmEntitySet=Util.getNavigationTargetEntitySet(startEdmEntitySet,edmNavigationProperty);
//第二:从后端获取数据
//首先获取URI的第一段指向的实体
//例如,类别(3)/产品首先找到单个实体:类别(3)
List keyPredicates=uriResourceEntitySet.getKeyPredicates();
实体sourceEntity=storage.readEntityData(startEdmEntitySet,keyPredicates);
//DemoService.svc/Categories(99)/产品等的错误处理
if(sourceEntity==null){
抛出新的ODataApplicationException(“未找到实体)”,HttpStatusCode.not_found.getStatusCode(),Locale.ROOT);
}
//然后获取实体导航到的实体集合
responseEntityCollection=storage.getRelatedEntityCollection(sourceEntity,targetEntityType);
}
}否则{//例如,产品(1)/类别/产品就是这种情况
抛出新的ODataApplicationException(“不受支持”,HttpStatusCode.Not_IMPLEMENTED.getStatusCode(),Locale.ROOT);
}
//第三:创建和配置序列化程序
ContextURL ContextURL=ContextURL.with().entitySet(responseEdmEntitySet.build();
最后一个字符串id=request.getRawBaseUri()+“/”+responseEdmEntitySet.getName();
EntityCollectionSerializerOptions opts=EntityCollectionSerializerOptions.with().contextURL(contextURL).id(id).build();
EdmEntityType EdmEntityType=responseEdmEntitySet.getEntityType();
ODataSerializer serializer=odata.createSerializer(responseFormat);
SerializerResult SerializerResult=serializer.entityCollection(this.srvMetadata,edmEntityType,responseEntityCollection,opts);
//第四:配置响应对象:设置主体、标题和状态代码
response.setContent(serializerResult.getContent());
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE,responseFormat.toContentTypeString());
}

简单地说,对于段的数量没有限制,
{serviceRoot}/Entity1('ID')/Entity2('ID')/Entity3)是有效的,其余部分由Shiva很好地解释了

感谢您的回复,我将研究它。你们是否碰巧有任何代码片段可以帮助我朝着正确的方向工作