OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

odata-comment message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: RE: [odata-comment] Re: DiscontinuedProducts is a really bad example


Hi Ron,

 

It is allowed that the target entity set of a navigation property varies from entity to entity. The next version of Part 3: CSDL will call that out explicitly:

 

13.4 Element edm:NavigationPropertyBinding

An entity set or a named entity SHOULD contain an edm:NavigationPropertyBinding element for each navigation property of its entity type and each complex type used in its properties.

If it is omitted, clients MUST assume that the target entity set or named entity can vary per related entity.

 

This is an extension with respect to V4. Partitioning one entity set into e.g. “Eastern” and “Western” as in Mike’s V3 example does no longer require also partitioning all entity sets of related entity types.

 

Bidirectional relationships are created by two navigation properties specifying each other as Partner. This is now explicitly mentioned in

 

7.1.4 Attribute Partner

A navigation property of an entity type MAY specify a navigation property path value for the Partner attribute.

This attribute MUST NOT be specified for navigation properties of complex types.

If specified, the value of this attribute MUST be a path from the entity type specified in the Type attribute to a navigation property defined on that type or a derived type. The path may traverse complex types, including derived complex types, but MUST NOT traverse any navigation properties. The type of the partner navigation property MUST be the containing entity type of the current navigation property or one of its parent entity types.

If the Partner attribute identifies a single-valued navigation property, the partner navigation property MUST lead back to the source entity from all related entities. If the Partner attribute identifies a multi-valued navigation property, the source entity MUST be part of that collection.

If no partner navigation property is specified, no assumptions can be made as to whether one of the navigation properties on the target type will lead back to the source entity.

If a partner navigation property is specified, this partner navigation property MUST either specify the current navigation property as its partner to define a bi-directional relationship or it MUST NOT specify a partner attribute. The latter can occur if the partner navigation property is defined on a complex type or the current navigation property is defined on a type derived from the type of the partner navigation property.

 

Thanks for your feedback!
--Ralf

 

From: odata-comment@lists.oasis-open.org [mailto:odata-comment@lists.oasis-open.org] On Behalf Of Ron Dagostino
Sent: Monday, 3. June 2013 14:10
To: Ram Jeyaraman (MS OPEN TECH)
Cc: Hartel, Barbara; odata-comment@lists.oasis-open.org
Subject: Re: [odata-comment] Re: DiscontinuedProducts is a really bad example

 

Regarding this proposed change I received:

"Other entity models may expose multiple entity sets per type. For instance, an entity model may have the followingthree entity sets:

<EntitySet Name="StandardCustomers" EntityType="Self.Customer">
 <NavigationPropertyBinding Path="Orders" EntitySet="Orders"/> 
</EntitySet>

<EntitySet Name="PreferredCustomers" EntityType="Self.Customer">

 <NavigationPropertyBinding Path="Orders" EntitySet="Orders"/> 
</EntitySet> 
<EntitySet Name="Orders" EntityType="Self.Order"/>

"

 

Thanks for making this change.  It is better than it was.  I believe there is still something that needs clarification, and there is something that is still stated incorrectly.

In the new example the StandardCustomers and PreferredCustomers entity sets define navigation property bindings from the Customer.Orders navigation property to the Orders entity set.  That's fine, but then the question arises regarding whether this relationship is unidirectional or bidirectional.  It probably would be bidirectional because it makes sense to want to navigate to the Customer from the Order.  How is this bidirectional relationship defined?  It could potentially be defined in one of two ways, and I believe some document somewhere should clarify which one it is because it is a fundamental issue.  One way to define it would be to have a single Order.Customer navigation property, but that would mean that for one instance of Order the navigation property would navigate to an entity from the StandardCustomers entity set and for another instance of Order the same navigation property wold navigate to an entity from the PreferredCustomers entity set.  Is it allowed for a navigation property's target entity set to change based on the entity set of the source entity? What happens if the navigation property multiplicity is "to-many" -- does that mean the collection could consist of entities from multiple entity sets?

The other way to define the above bidirectional relationship is to create two navigation properties on the Order entity -- one called PreferredCustomer and the other called StandardCustomer.  Then one navigation property would navigate to an instance and the other would not.

Whether a navigation property's target entity set is static and must be defined at "declaration time" vs. whether it can float depending on the originating entity set of the source entity is a fundamental issue that requires clarification.

Also, I provided the following feedback that was not addressed because section 13.3.1 remains unchanged:


<<<I believe Section 13.3.1 of the CSDL (Attribute Path) incorrectly states
<<<"navigation property bindings are only used when all related entities are known to come from a single entity set".
<<<I believe it is pretty much the reverse --- they are only necessary when related entities are known to come from
<<<multiple entity sets; otherwise the navigation property binding can be derived and it is superfluous to explicitly specify it.


Although it is true that the new example in Section 13.3 shows that navigation property bindings are used on the {Standard,Preferred}Customers entity sets because the related entities are known to come from the single Orders entity set, it is not true that navigation property bindings are only used in such a case.  In Mike Pizzo's {Eastern,Western}Region{Orders,Customers} example that I referred to it is in fact necessary to use navigation property bindings to point the EasternRegionOrder.Customer navigation property to the EasternRegionCustomers entity set and to point the WesternRegionOrder.Customer navigation property to the WesternRegionCustomers entity set.  In this case clearly the related entities are known to come from multiple entity sets, which is in direct contradiction to the current wording of section 13.3.1.

Again, thanks for improving the doc based on my feedback, and I will look forward to further communication regarding the above comments.

Ron


On May 17, 2013, at 7:33 PM, "Ram Jeyaraman (MS OPEN TECH)" <Ram.Jeyaraman@microsoft.com> wrote:

Ron, thanks the additional information.

 

The Technical Committee is presently discussing this. We will respond back to you soon.

 

From: odata-comment@lists.oasis-open.org [mailto:odata-comment@lists.oasis-open.org] On Behalf Of Ron Dagostino
Sent: Thursday, May 16, 2013 12:59 PM
To: odata-comment@lists.oasis-open.org
Subject: [odata-comment] Re: DiscontinuedProducts is a really bad example

 

I suspect the NavigationPropertyBinding may need an optional "Partner" attribute in order for it to handle the case where both sides of the relationship are segmented but they are not segmented in a parallel manner.  For example, consider the case where Order is segmented as Mike suggests across Eastern vs. Western regions.  Now consider what happens if Product is also segmented, but it is segmented in an manner totally different than by region -- perhaps according to different business lines (that may have been acquired and integrated at different times, for example).  So you have BusinessLine1Products, BusinessLine2Products, etc.  Now you have to define the MxN different combinations where M and N are the number of times each side is segmented.  Currently the spec only handles parallel segmentation (Order and Customer both segmented by Region, for example) or segmentation on one side only (unsegmented Product related to Customer segmented by region).  For orthogonal segmentation you need to the ability to specify something like this:

For Entity Set EasternRegionOrders, map the BusinessLine1Products navigation property to the BusinessLine1Products entity set with the partner EasternRegionOrders AND ALSO MAP IT to the BusinessLine2Products entity set with the partner EasternRegionOrders.

For Entity Set WesternRegionOrders, map the BusinessLine1Products navigation property to the BusinessLine1Products entity set with the partner WesternRegionOrders AND ALSO MAP IT to the BusinessLine2Products entity set with the partner WesternRegionOrders.

Similarly, on the other side:

For Entity Set BusienssLine1Products, map the EasternRegionOrders navigation property to the EasternRegionOrders entity set with the partner BusinessLine1Products, AND ALSO MAP IT to the WesternRegionOrders entity set with the partner BusinessLine1Products.

For Entity Set BusienssLine2Products, map the EasternRegionOrders navigation property to the EasternRegionOrders entity set with the partner BusinessLine2Products AND ALSO MAP IT to the WesternRegionOrders entity set with the partner BusinessLine2Products.

I know that this is getting a little ridiculous -- what are the chances of this happening?  -- but in the interest of being complete it might be appropriate to allow something like this:

 

<EntitySet Name="EasternRegionOrders" ...>

<NavigationPropertyBinding Path="BusinessLine1Products" Partner="EasternRegionOrders" EntitySet="BusinessLine1Products"/>
<NavigationPropertyBinding Path="BusinessLine2Products" Partner="EasternRegionOrders" EntitySet="BusinessLine2Products"/>
</EntitySet>

<EntitySet Name="WesternRegionOrders" ...>

<NavigationPropertyBinding Path="BusinessLine1Products" Partner="WesternRegionOrders" EntitySet="BusinessLine1Products"/>
<NavigationPropertyBinding Path="BusinessLine2Products" Partner="WesternRegionOrders" EntitySet="BusinessLine2Products"/>
</EntitySet>

<EntitySet Name="BusinessLine1Products" ...>

<NavigationPropertyBinding Path="EasternRegionOrders" Partner="BusinessLine1Products" EntitySet="EasternRegionOrders"/>
<NavigationPropertyBinding Path="WesternRegionOrders" Partner="BusinessLine1Products" EntitySet="WesternRegionOrders"/>
</EntitySet>

<EntitySet Name="BusinessLine2Products" ...>

<NavigationPropertyBinding Path="EasternRegionOrders" Partner="BusinessLine2Products" EntitySet="EasternRegionOrders"/>
<NavigationPropertyBinding Path="WesternRegionOrders" Partner="BusinessLine2Products" EntitySet="WesternRegionOrders"/>
</EntitySet>

It is currently not possible to disambiguate the partner solel;y from the metadata in cases where both sides of a relationship are segmented in an orthogonal manner -- an optional Partner attribute on NavigationPropertyBinding seems to be one way to resolve the issue.

Ron

 

On Mon, May 13, 2013 at 2:36 PM, Ron Dagostino <rndgstn@gmail.com> wrote:

Also, I believe Section 13.3.1 of the CSDL (Attribute Path) incorrectly states "navigation property bindings are only used when all related entities are known to come from a single entity set".  I believe it is pretty much the reverse --- they are only necessary when related entities are known to come from multiple entity sets; otherwise the navigation property binding can be derived and it is superfluous to explicitly specify it.

Section 7.1.4 of the CSDL (Attribute Partner) should perhaps specify something similar -- that the partner attribute is only necessary when an entity type or its subtypes that participates in the relationship on either side have more than one navigation property to the type on the other side of the relationship; otherwise the partner can be derived and it is superfluous to explicitly specify it.

 

On Mon, May 13, 2013 at 1:05 PM, Ron Dagostino <rndgstn@gmail.com> wrote:

I believe the example below helps to illustrate when NavigationProperty.Partner and EntitySet.NavigationPropertyBinding are superfluous vs. required.  Using Mike's example, Order and Customer instances are segmented across Eastern vs. Western region entity sets; furthermore, for illustration, Order has a relationship to Product, and Product is not segmented by region.  It seems to me that NavigationProperty.Partner is required when disambiguation between multiple possible partners is necessary, and EntitySet.NavigationPropertyBinding is required when disambiguation between multiple possible entity sets is necessary.  It is superfluous to specify when a relationship is unidirectional, but it may not be clear at a glance, so perhaps adding an optional "Unidirectional" attribute to NavigationProperty would be helpful (though its default value cannot be simply false, which means perhaps adding it isn't such a good idea after all because its value would have to match the value that it is constrained to be -- so perhaps just putting in a comment somehow is best).  Anyway, I think it would be more than helpful to eliminate the "DiscontinuedProduct" example in favor of something like Mike's example and also provide information on how/when to use Partner and NavigationPropertyBinding.

 

Ron

(EntityType.Order).Customer.Type = Customer

(EntityType.Order).Customer.Partner = Orders (superfluous when Customer has only 1 navigation property to Order entities)

 

(EntityType.Customer).Orders.Type = Collection(Order)

(EntityType.Customer).Orders.Partner = Customer (superfluous when Order has only 1 navigation property to Customer entities)

 

(EntitySet.EasternRegionOrders).NavigationPropertyBinding.Path = Customer

(EntitySet.EasternRegionOrders).NavigationPropertyBinding.EntitySet = EasternRegionsCustomers (required to disambiguate Eastern/WesternRegionCustomers)

(EntitySet.WesternRegionOrders).NavigationPropertyBinding.Path = Customer

(EntitySet.WesternRegionOrders).NavigationPropertyBinding.EntitySet = WesternRegionCustomers (required to disambiguate Eastern/WesternRegionCustomers)

 

(EntitySet.EasternRegionCustomers).NavigationPropertyBinding.Path = Orders

(EntitySet.EasternRegionCustomers).NavigationPropertyBinding.EntitySet = EasternRegionOrders (required to disambiguate Eastern/WesternRegionOrders)

(EntitySet.WesternRegionCustomers).NavigationPropertyBinding.Path = Orders

(EntitySet.WesternRegionCustomers).NavigationPropertyBinding.EntitySet = WesternRegionOrders (required to disambiguate Eastern/WesternRegionOrders)

 

 

(EntityType.Product).EasternRegionOrders.Type = Collection(Order)

(EntityType.Product).EasternRegionOrders.Partner = Products (superfluous when Order has only 1 navigation property to Product entities)

(EntityType.Product).WesternRegionOrders.Type = Collection(Order)

(EntityType.Product).WesternRegionOrders.Partner = Products (superfluous when Order has only 1 navigation property to Product entities)

 

(EntityType.Order).Products.Type = Collection(Product)

(EntityType.Order).Products.Partner = <<<must be omitted because it is ambiguous: both EasternRegionOrders and WesternRegionOrders are valid>>>

 

(EntitySet.Products).NavigationPropertyBinding.Path = EasternRegionOrders

(EntitySet.Products).NavigationPropertyBinding.EntitySet = EasternRegionOrders (required to disambiguate Eastern/WesternRegionOrders)

(EntitySet.Products).NavigationPropertyBinding.Path = WesternRegionOrders

(EntitySet.Products).NavigationPropertyBinding.EntitySet = WesternRegionOrders (required to disambiguate Eastern/WesternRegionOrders)

 

(EntitySet.EasternRegionOrders).NavigationPropertyBinding.Path = Products

(EntitySet.EasternRegionOrders).NavigationPropertyBinding.EntitySet = Products (superfluous when Products is the only EntitySet of type Product)

(EntitySet.WesternRegionOrders).NavigationPropertyBinding.Path = Products

(EntitySet.WesternRegionOrders).NavigationPropertyBinding.EntitySet = Products (superfluous when Products is the only EntitySet of type Product)

 

 

On Sun, May 12, 2013 at 11:37 PM, Ron Dagostino <rndgstn@gmail.com> wrote:

Section 13 of the CSDL document gives this example:

 

"Other entity models may expose multiple entity sets per type. For instance, an entity model may have the following entity sets:

<EntitySet Name="Products" EntityType="Self.Product"/>
<EntitySet Name="DiscontinuedProducts" EntityType="Self.Product"/>

"

 

This is a really bad example at best.  It means a Product instance changes its entity set when it becomes discontinued, and that means any existing relationships to it become illegal.  There are still Order instances that need to refer to it (assuming it was ordered before it was discontinued), but now they can't intuitively refer to it because it doesn't exist in the Products entity set anymore -- it moved to the DiscontinuedProducts entity set.  An Order entity would need to a DiscontinuedProduct navigation property in order to refer to it.

 

Mike Pizzo provides a better example of exposing a single type across multiple entity sets here (http://mailinglist.odata.org/scripts/wa-ODATA.exe?A2=ODATA;bc4700a0.1302).  Including this example would not only provide a correct example, but it would also demonstrate a situation where the new NavigationPropertyBinding element of EntitySet is required in order to disambiguate the target entity sets of navigation properties.

 

Way to go on the whole simplification of relationships and removal of Association and AssociationSet.

 

A clearly articulated example of unidirectional relationships along with when EntitySet.NavigationPropertyBinding and NavigationProperty.Partner are optional vs. required would be helpful.  Right now they are labelled SHOULD and MAY, respectively, but there are cases where they are required (Mike's example above I believe is one of them), and it would be helpful if the docs gave good examples that fully described when these optional elements are actually required.  It is also potentially confusing because the lack of a Partner attribute could be misconstrued as meaning the relationship is unidirectional.  It might be best to add a "Unidirectional" attribute to the NavigationProperty element that defaults to false but must be set to true when the relationship is unidirectional -- then the lack of a Partner attribute alone cannot be misconstrued as implying a unidirectional relationship when in fact it is simply omitted because it adds no meaning in a particular context.

 

Ron

 

 

 

 




[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]