1

I am trying to communicate breeze.js with OData server (XPO based). In metadata xml which comes from server navigation properties are exists but they are not created for client types' metadata. Am I doing something wrong or is there a bug?

Server metadata xml:

http://odataserver/Db.svc/$metadata

    <edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" Version="1.0">
<edmx:DataServices xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" Namespace="Namespace">
<EntityType Name="Question">
<Key>
<PropertyRef Name="Oid"/>
</Key>
<Property Name="Oid" Type="Edm.Int32" Nullable="false"/>
<Property Name="No" Type="Edm.String"/>
<Property Name="Header" Type="Edm.String"/>
<NavigationProperty Name="Chapter" Relationship="Namespace.Question_Chapter_Chapter_Questions" ToRole="Chapter_Questions" FromRole="Question_Chapter"/>
</EntityType>
<EntityType Name="Chapter">
<Key>
<PropertyRef Name="Oid"/>
</Key>
<Property Name="Oid" Type="Edm.Int32" Nullable="false"/>
<Property Name="No" Type="Edm.String"/>
<Property Name="Name" Type="Edm.String"/>
<NavigationProperty Name="Questions" Relationship="Namespace.Question_Chapter_Chapter_Questions" ToRole="Question_Chapter" FromRole="Chapter_Questions"/>
</EntityType>
<Association Name="Question_Chapter_Chapter_Questions">
<End Type="Namespace.Chapter" Role="Chapter_Questions" Multiplicity="0..1"/>
<End Type="Namespace.Question" Role="Question_Chapter" Multiplicity="*"/>
</Association>
<EntityContainer Name="DbService" m:IsDefaultEntityContainer="true">
<EntitySet Name="Question" EntityType="Namespace.Question"/>
<EntitySet Name="Chapter" EntityType="Namespace.Chapter"/>
<AssociationSet Name="Question_Chapter_Chapter" Association="Namespace.Question_Chapter_Chapter_Questions">
<End Role="Question_Chapter" EntitySet="Question"/>
<End Role="Chapter_Questions" EntitySet="Chapter"/>
</AssociationSet>
</EntityContainer>
<Annotations Target="Namespace.Chapter/No">
<ValueAnnotation Term="Org.OData.Validation.V1.Size" Int="100"/>
</Annotations>
<Annotations Target="Namespace.Chapter/Name">
<ValueAnnotation Term="Org.OData.Validation.V1.Size" Int="100"/>
</Annotations>
<Annotations Target="Namespace.Question/No">
<ValueAnnotation Term="Org.OData.Validation.V1.Size" Int="100"/>
</Annotations>
<Annotations Target="Namespace.Question/Header">
<ValueAnnotation Term="Org.OData.Validation.V1.Size" Int="100"/>
</Annotations>
</Schema>
</edmx:DataServices>
</edmx:Edmx>

Question has a navigation property:

<NavigationProperty Name="Chapter" Relationship="Namespace.Question_Chapter_Chapter_Questions" ToRole="Chapter_Questions" FromRole="Question_Chapter"/>

But when I issue command:

manager.metadataStore.getEntityType("Question")

after loading metadata to breeze, result has 0 item in navigationProperties array.

Gökçer Gökdal
  • 950
  • 1
  • 11
  • 18

1 Answers1

1

I found the problem by debugging breeze.js library. Breezejs is silently! ignoring navigation properties if there are no constraints defined. I think it should at least print warning about it to javascript console. I will make a push request about it. Problematic line in breeze.debug.js is below.

  function parseCsdlNavProperty(entityType, csdlProperty, schema) {

   ...

    var constraint = association.referentialConstraint;
    if (!constraint) {
        // TODO: Revisit this later - right now we just ignore many-many and assocs with missing constraints.
        return;
        // Think about adding this back later.
        //if (association.end[0].multiplicity == "*" && association.end[1].multiplicity == "*") {
        //    // many to many relation
        //    ???
        //} else {
        //    throw new Error("Foreign Key Associations must be turned on for this model");
        //}
    }

 ...
}

Because of constraint is being undefined, method silently returns and ignores the navigation property. I think this behaivor should also be defined in breeze.js documentation.

Gökçer Gökdal
  • 950
  • 1
  • 11
  • 18
  • I agree and will add it to our list of needed doc enhancements. But I would also like to call out that if the constraint really does exist and XPO ignores it that this is ALSO an XPO issue. Why do they not generate constraints? We've seen this with other OData providers that only implement a part of the spec. – Jay Traband Mar 11 '14 at 02:57
  • Hi Jay. I strongly agree with you. I am also evaluating JayData and Microsoft Entity Framework OData support too. Let me share my findings. Jaydata ignores constraint requirements and generate navigation behavior without problem. Also Microsoft ER OData layer is not supplying constraints although there are associations in the first pass. You are right by requiring constraints. Reality is most of OData providers have problems with constraints and they could not be fixed by configuration especially with XPO OData provider. I found breeze's object management is better architected. So (cont.) – Gökçer Gökdal Mar 11 '14 at 14:09
  • (cont.) keeping in mind that Breeze.js is a consumer for OData services I think it should be more forgiving like JayData and generate navigation properties without constraints assuming how they should be. It should also generate warnings to javascript console in this situation. As a workaround I will write a javascript file generator in Node.js including typescript definitions like JayData jaysvcutil.exe which will define schema by code and add navigation properties regardless of having constraints. I will share it when it finishes. Again I liked Breeze.js very much. – Gökçer Gökdal Mar 11 '14 at 14:13