Skip to content

Metadata API

This API is used to interrogate the service metadata document of the OData provider. Both Dynamic API and proxy classes use this API for their functionality. When an application uses this API, it is usually because it needs to discover the data model at run time for a number of very specific use cases.

The API maps closely to the contents of the service metadata document, also known as the Common Schema Definition Language (CSDL) document. Therefore, as long as the items and their relationships in the CSDL for a particular version of OData are understood, usage of the API follows naturally.

Metadata API is contained in the package.


Metadata may be loaded online as the application starts or embedded within the generated classes with a supplied XML document. Once loaded by the Metadata API, it resides in memory and can be interrogated by the application. The generic class, DataService, returns an instance of CsdlDocument using the getMetadata method. It is from this CsdlDocument instance that we can go through the data model.

CsdlDocument csdlDocument = dataService.getMetadata();
val csdlDocument = dataService.metadata

The CSDL document has a hierarchical structure that includes entity containers as the logical containers of entity sets and service operations.


Unless you are sure that there is only one entity container in the service metadata document, it is recommended that you start the metadata interrogation through the entity container. With OData version 2 and version 3, there can be multiple entity containers within a service metadata document and one of those is marked as the default container. Containers can be accessed from the CSDL document as follows:

EntityContainer container = csdlDocument.getDefaultContainer();
val container = csdlDocument.defaultContainer

We can also access the entity container using its qualified name, <namespace>.<container name>, for example, ODataAPI.EventService.

EntityContainerMap containerMap = csdlDocument.getEntityContainers();
EntityContainer container = containerMap.get("ODataAPI.EventService");
val containerMap = csdlDocument.entityContainers
val container = containerMap.get("ODataAPI.EventService")


While entity sets are defined within an entity container, the CsdlDocument instance has a map of all the entity sets from all the containers. You can get the entity set directly from the CsdlDocument instance or from a container.

// From default container
EntitySet eventSet = csdlDocument.getEntitySet("Events");
// OR from EventService container
EntitySet eventSet = csdlDocument.getEntitySet("EventService.Events");
// From default container
val eventSet = csdlDocument.getEntitySet("Events")
// OR from EventService container
val eventSet = csdlDocument.getEntitySet("EventService.Events")

The CsdlDocument getEntitySet method can handle both qualified name and local name. On the other hand, if you want to make sure the entity set being retrieved is within the container, use the following:

EntityContainer container = csdlDocument.getDefaultContainer();
EntitySetMap entitySetMap = container.getEntitySets();
EntitySet eventSet = entitySetMap.get("Events");
val container = csdlDocument.defaultContainer
val entitySetMap = container.entitySets
val eventSet = entitySetMap.get("Events")


Each CSDL document has within it the definition of each entity type. Therefore, it is possible to get the map of all entity types defined within the document. The entity type is retrieved using the qualified name, which consists of the namespace and the entity type name.

If there is no entity for the name specified when using the getEntityType method of CsdlDocument, an undefined error will be thrown.

EntityType eventType = csdlDocument.getEntityType("ODataAPI.Event");

EntityTypeMap entityTypeMap = csdlDocument.getEntityTypes();
EntityType eventType = entityTypeMap.get("ODataAPI.Event");
val eventType = csdlDocument.getEntityType("ODataAPI.Event")

val entityTypeMap = csdlDocument.entityTypes
val eventType = entityTypeMap.get("ODataAPI.Event")

You can also start from the container by looking for the entity set containing the entity type and then get the entity type as follows:

EntityContainer container = csdlDocument.getDefaultContainer();
EntitySetMap entitySetMap = container.getEntitySets();
EntitySet eventSet = entitySetMap.get("Events");
// Get entity type for entity set Events
EntityType eventType = event.getEntityType();
val container = csdlDocument.defaultContainer()
val entitySetMap = container.entitySets
val eventSet = entitySetMap.get("Events")
// Get entity type for entity set Events
val eventType = eventSet.entityType


Following the OData version 4 nomenclature, properties are either structural or navigational. Both types are contained within the same property map returned by the entity type.

PropertyMap properties = eventType.getPropertyMap();
// Get structural property
Property nameProp = properties.get("Name");
// Get navigation property
Property sessionsProp = properties.get("Sessions");
val propertyMap = eventType.getPropertyMap()
// Get structural property
val nameProp = propertyMap.get("Name")
// Get navigation property
val sessionsProp = propertyMap.get("Sessions")


Because the Android SDK is based on the OData version 4 specification, associations and association sets are no longer available. You can instead determine whether a navigation property is referring to multiple instances or a single instance by using the isList method.

Use Case

In most cases, you are not likely to need to use the Metadata API when creating your applications. You can look up entity sets, entity types, and properties using the proxy classes or Dynamic API as long as you have a prior knowledge of the data model. For example, you will need to know the name of the entity set to look it up.

The Metadata API can support discovery of the data model at runtime. There is no need to know any of the names. Instead, you can start from the entity container, iterate through all the entity sets, examine the entity types associated with the entity set, and visit all the properties of the entity type.

Refer to the code fragment for information on iterating through all the entity sets and retrieving every collection from the provider. For each entity set, the corresponding entity type is used to get the values of its structural properties as a string.

Last update: August 12, 2020