-
Type:
New Feature
-
Status: Closed
-
Priority:
Major
-
Resolution: Fixed
-
Affects Version/s: V4.0_CSD03
-
Fix Version/s: V4.0_CSD04
-
Component/s: Data Aggregation, Vocabularies
-
Labels:None
-
Environment:
Proposed
-
Proposal:Hide
Make use of existing specification text in section 14.2.2 Target.
For vocabulary terms Aggregation.CustomAggregate and Aggregation.ApplySupported, add AppliesTo="Collection" and tag these terms with a new annotation in the Core vocabulary:
<Term Name="AppliesViaContainer" Type="Core.Tag" DefaultValue="true" Nullable="false" AppliesTo="Term"> <Annotation Term="Core.Description" String="The target path of an annotation with this term must start with an entity container or the annotation must be embedded within an entity container, entity set or singleton"/> </Term>
Deprecate terms Groupable, Aggregatable, complex type NavigationPropertyAggregationCapabilities.
For compatibility reasons, do not use this technique for annotations in the Capabilities vocabulary.
ShowMake use of existing specification text in section 14.2.2 Target . For vocabulary terms Aggregation.CustomAggregate and Aggregation.ApplySupported , add AppliesTo="Collection" and tag these terms with a new annotation in the Core vocabulary: <Term Name= "AppliesViaContainer" Type= "Core.Tag" DefaultValue= "true" Nullable= "false" AppliesTo= "Term" > <Annotation Term= "Core.Description" String= "The target path of an annotation with this term must start with an entity container or the annotation must be embedded within an entity container, entity set or singleton" /> </Term> Deprecate terms Groupable , Aggregatable , complex type NavigationPropertyAggregationCapabilities . For compatibility reasons, do not use this technique for annotations in the Capabilities vocabulary.
NavigationPropertyBindings are used to assign an entity set to a Path ending in a non-containment navigation property. The assigned entity set can then be the target for annotations like Aggregation.CustomAggregate (see https://issues.oasis-open.org/browse/ODATA-1382).
Paths ending in a containment navigation property, which implicitly define an entity set, are treated totally different, however. In order to define a custom aggregate on this implicit entity set, the annotation Capabilities.NavigationRestrictions with type Aggregation.NavigationPropertyAggregationCapabilities/CustomAggregates must be used.
An easier alternative would be to use external targeting with a path that ends in a containment navigation property:
<Annotations Target="namespace.ContainerName/me/Mails"> <Annotation Term="Aggregation.CustomAggregate" Qualifier="JunkRating" String="Edm.Int32"/> </Annotations>
A NavigationPropertyBindingVariant (working title) would have to be allowed as an annotation target, e.g., as
<Annotations Target="me/Mails/$NavigationPropertyBindingVariant">
To be in line with the other targets (start from schema child, then dive into structure), it would rather be
<Annotations Target="namespace.ContainerName/me/$NavigationPropertyBindingVariant/Mails">
OK. What about replacing the working title with ContainmentNavigationProperty? (Without a Target, we shouldn't speak of a binding, right?)
If we support external targeting only, can we even avoid the new object ContainmentNavigationProperty? Add a sentence to OData-CSDL, section 8.4:
An annotation whose term applies to an entity set can also target the implicit entity set defined by a containment navigation property. The path expression for such a target must end in a containment navigation property followed by /$EntitySet
Example:
<Annotations Target="namespace.ContainerName/me/Mails/$EntitySet"> <Annotation Term="Aggregation.CustomAggregate" Qualifier="JunkRating" String="Edm.Int32"/> </Annotations>
In order to address such annotations in a Path, the path syntax must be extended to include something like
<Path>me/Mails/@Aggregation.CustomAggregate</Path>
The current target syntax in 14.2.2 Target already allows navigation segments after an entity set:
External targeting is also possible for properties and navigation properties of singletons or entities in a particular entity set. These annotations override annotations on the properties or navigation properties targeted via the declaring structured type.
- [...]
- qualified name of an entity container followed by a segment containing a singleton or entity set name and zero or more property, navigation property, or type-cast segments
This seems to cover already the desired feature without requiring new syntax.
But such annotations then target the navigation property (in our example, Mails), not the (implicit or explicit) entity set at the navigation property's target.
So what's the problem / the difference?
Doesn't it make a difference whether you annotate an entity set or a navigation property?
Conceptually entity sets and singletons are containment navigation properties of the implicit "service entity type" of the entity container.
I want to annotate the implicit entity set that is defined by the containment navigation property Mails on the singleton me. Then I cannot use the target namespace.ContainerName/me/Mails because that addresses the containment navigation property. But I want to address the implicit entity set.
The navigation property is addressed via namespace.entityTypeOfMe/Mails. And the type of the Mails property via namespace.typeOfMails.
Do we really need syntax to differentiate between
- the implicit entity set defined by the Mails containment navigation property of singleton me, and
- the use of type namespace.typeOfMails as the type of the property Mails of the singleton me?
Note that the proposed extension of a term definition makes sense only for containment navigation properties and the implicit entity sets they define. An "entity set defined by a non-containment navigation property" (via NavigationPropertyBinding) is just a named entity set and can be annotated as such.
I believe that capabilities and other annotations of such an entity set should not depend on the path via which the entity set is reached, because the entity set exists independently of that path. This is different for implicit entity sets, which are contained in an instance from another entity set (or singleton), hence they are dependent on the path.
In other words: Path-dependent capabilities and annotations make sense only for implicit entity sets, i.e., for containment navigation properties.
Example: An entity set Orders has two navigation properties
- items – contained in Order
- superImportantItems – non-contained projection on “items” in same entity
Then capabilities should be annotated for the "defining path" Orders/items, but not for the "reference path" Orders/superImportantItems.
In cases where annotations of an explicit (named) entity set shall depend on the path, Capabilities.NavigationPropertyRestrictions can be used instead.
Will try to rephrase so that non-containment navigation properties are also covered.
- Discourage Groupable, Aggregatable, NavigationPropertyAggregationCapabilities
- Can AppliesViaContainer be combined with AppliesTo="ComplexType"?
- AppliesViaContainer also for AvailableOnAggregates?
- What about Capabilities vocabulary?
- ChangeTracking
- NavigationRestrictions
- OperationRestrictions
- ModificationQueryOptions
- MediaLocationUpdateSupported
Are the following statements true or false?
The annotation from the example given in the description can be addressed via the path
/namespace.ContainerName/me/Mails/@Aggregation.CustomAggregate#JunkRating
(using a term cast, like in OData-CSDL, example 61).
The annotation from the example given in the description can be addressed via the path
/namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating
(without term cast, like in [OData-CSDL, example 64]).
I would like the first to be true (important to me!) and the second false (less important to me). But is that what the spec says?
Examples 61 and 64 talk about paths in annotation expressions, for example in an AnnotationPath:
- use example-61 syntax to address an annotation that is attached to the target type of the navigation property
- use example-64 syntax to address an annotation that is attached to the navigation property itself
The annotation example in the description uses external targeting, so it attaches the annotation to the navigation property itself, and an AnnotationPath expression has to use example-64 syntax to address this annotation.
You can use example-61 syntax if the annotation would target the entity type that is referenced in the Mails navigation property, e.g. namespace.MailType.
OK, you convinced me.
2021-3-11 - Decided to defer resolution of this issue until we decide our intentions for representing the existing non-aggregation navigation property restrictions.
"Core" navigation property restrictions could be represented by the Capabilities.NavigationPropertyRestriction type, but all non-core ones (whether from the Aggregation vocabulary or some other, perhaps future, vocabulary) cannot: Because if every vocabulary introduced its own sub-type (like Aggregation.NavigationPropertyAggregationCapabilities has done), a given Capabilities.NavigationRestrictions/RestrictedProperties annotation could choose only one of these subtypes, so it could not express both a custom aggregate and a restriction from a future vocabulary on the same NavigationProperty. (No multiple inheritance.)
On the other hand, it is infeasible if every vocabulary had to insert its restrictions into the Capabilities.NavigationPropertyRestriction type.
Good point!
Maybe we should add mixins in V5 �
An annotation like
/namespace.ContainerName/me/Mails@Aggregation.CustomAggregate#JunkRating
can be addressed via an Edm.AnnotationPath, for example in a bar chart annotation if the aggregated value shall be represented as the height of a bar.
By contrast, the Edm.PropertyPath
/namespace.ContainerName/me/@Capabilities.NavigationRestrictions /RestrictedProperties/1/CustomAggregates/0
is much more cumbersome (especially the index segments) and, not being an Edm.AnnotationPath, cannot be governed by Validation.AllowedTerms.
Note: there are solutions to having multiple vocabularies extend NavigationRestrictions (for example, through dynamic properties).
2021-03-18
How would "external targeting" work for Navigation Property Bindings? Most SAP tools only use "external targeting" syntax.