2.2.1.6 Containment

Applies to the OData 3.0 protocol

Containment is specified by using a containment NavigationProperty. A containment NavigationProperty is a NavigationProperty that has a ContainsTarget attribute set to "true".

The EntityType that declares the NavigationProperty is the container EntityType.

The AssociationType that is specified in the containment NavigationProperty is the containment AssociationType.

The EntityType specified on the End of the containment AssociationType, with the Name specified by the containment NavigationProperty ToRole attribute, is the contained EntityType.

When the instances of both contained and container entities reside in the same EntitySet, this is called recursive containment.

It MUST NOT be possible for an EntityType to contain itself by following more than one containment NavigationProperty.

The contained EntityType MAY have a NavigationProperty that navigates to the container EntityType via the containment AssociationType. The End of the containment AssociationType that is specified by the ToRole attribute of the containment NavigationProperty a have any multiplicity.

For nonrecursive containment, the End of the containment AssociationType that is specified by the FromRole attribute of the containment NavigationProperty MUST have a multiplicity of '1'.

For recursive containment, the End of the containment AssociationType that is specified by the FromRole attribute of the containment NavigationProperty MUST have a multiplicity of '0..1'. Additionally, the End specified by the ToRole MUST NOT have a multiplicity of '1' because this would lead to endless recursion.

An AssociationSet MUST have the same EntitySet on both ends if it is for a containment AssociationType that has either the same EntityType on both ends or an EntityType on one end that derives from an EntityType on the other end.

An EntitySet MUST NOT be bound by AssociationSet to more than one AssociationType via a containment NavigationProperty that indicates that the EntityType (or derived EntityTypes) of that EntitySet is contained.

Note Because the EntityType of EntitySets on an AssociationSet End is the same as or derived from the EntityTypes on the corresponding AssociationType Ends, an EntitySet is either completely contained or completely noncontained.

Nonrecursive contained EntitySets are accessed only through the URL of the resource that represents the containment NavigationProperty on the parent Entity instance. Clients MUST NOT assume that nonrecursive contained EntitySets can be accessed directly from the ServiceRoot.

Recursively contained EntitySets MUST be accessible directly from the ServiceRoot for querying and inserting "root" entity instances that are not contained by another instance. Entity instances that are contained by another entity instance, the querying and inserting operations are supported via the URL of the resource that represents the container NavigationProperty on the parent entity instance.

When the end of the containment AssociationType that is specified by the ToRole attribute of the containment NavigationProperty is '1' or '0..1', there is no way to independently insert the contained entity by using a simple InsertEntity Request (section 2.2.7.1.1). A simple InsertEntity request would require supporting POST to a URL that represents a ReferenceSet, and a POST to a URL that represents a ReferenceSet is inconsistent with existing protocol semantics. This type of contained entity can still be created either by using a "deep insert" (section 2.2.7.1.1) that creates both the container and the contained entities in one request or by invoking an action (section 4.8) that creates the contained entity.