entityrepository / ODataServer

Enhances Web API OData functionality, featuring generic OData controllers that can be generated from a domain model, including any Entity Framework DbContext.
15 stars 4 forks source link

EntityRepository $metadata is not Breeze-compatible #7

Open johncrim opened 9 years ago

johncrim commented 9 years ago

(previously http://entityrepository.codeplex.com/workitem/12)

As documented here: http://www.getbreezenow.com/documentation/odata-server Section: Metadata fail!

tldr: The EntityRepository $metadata is not usable within Breeze, b/c it uses ODataConventionModelBuilder, which doesn't produce correct foreign keys; Breeze relies upon them.

For example, using the Breeze TodoList example, this /odata/$metadata works with Breeze:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <edmx:DataServices m:DataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <Schema Namespace="ODataBreezejsSample.Models" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
      <EntityType Name="TodoItem" p5:ClrType="ODataBreezejsSample.Models.TodoItem, ODataBreezejsSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:p5="http://schemas.microsoft.com/ado/2013/11/edm/customannotation">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" p7:StoreGeneratedPattern="Identity" xmlns:p7="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
        <Property Name="TodoListId" Type="Edm.Int32" Nullable="false" />
        <Property Name="Description" Type="Edm.String" Nullable="false" MaxLength="60" FixedLength="false" Unicode="true" />
        <Property Name="IsDone" Type="Edm.Boolean" />
        <NavigationProperty Name="TodoList" Relationship="ODataBreezejsSample.Models.TodoList_TodoItems" ToRole="TodoList_TodoItems_Source" FromRole="TodoList_TodoItems_Target" />
      </EntityType>
      <EntityType Name="TodoList" p5:ClrType="ODataBreezejsSample.Models.TodoList, ODataBreezejsSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns:p5="http://schemas.microsoft.com/ado/2013/11/edm/customannotation">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" p7:StoreGeneratedPattern="Identity" xmlns:p7="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
        <Property Name="Title" Type="Edm.String" Nullable="false" MaxLength="30" FixedLength="false" Unicode="true" />
        <Property Name="Created" Type="Edm.DateTime" Nullable="false" />
        <NavigationProperty Name="TodoItems" Relationship="ODataBreezejsSample.Models.TodoList_TodoItems" ToRole="TodoList_TodoItems_Target" FromRole="TodoList_TodoItems_Source" />
      </EntityType>
      <Association Name="TodoList_TodoItems">
        <End Type="ODataBreezejsSample.Models.TodoList" Role="TodoList_TodoItems_Source" Multiplicity="1">
          <OnDelete Action="Cascade" />
        </End>
        <End Type="ODataBreezejsSample.Models.TodoItem" Role="TodoList_TodoItems_Target" Multiplicity="*" />
        <ReferentialConstraint>
          <Principal Role="TodoList_TodoItems_Source">
            <PropertyRef Name="Id" />
          </Principal>
          <Dependent Role="TodoList_TodoItems_Target">
            <PropertyRef Name="TodoListId" />
          </Dependent>
        </ReferentialConstraint>
      </Association>
      <EntityContainer Name="TodoListContext" p5:UseClrTypes="true" xmlns:p5="http://schemas.microsoft.com/ado/2013/11/edm/customannotation">
        <EntitySet Name="TodoItems" EntityType="ODataBreezejsSample.Models.TodoItem" />
        <EntitySet Name="TodoLists" EntityType="ODataBreezejsSample.Models.TodoList" />
        <AssociationSet Name="TodoList_TodoItems" Association="ODataBreezejsSample.Models.TodoList_TodoItems">
          <End Role="TodoList_TodoItems_Target" EntitySet="TodoItems" />
          <End Role="TodoList_TodoItems_Source" EntitySet="TodoLists" />
        </AssociationSet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

(Note the single Association, and single AssociationSet)

This $metadata does not work:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0" xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
  <edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
    <Schema Namespace="ODataBreezejsSample.Models" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
      <EntityType Name="TodoItem">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
        <Property Name="TodoListId" Type="Edm.Int32" Nullable="false" />
        <Property Name="Description" Type="Edm.String" Nullable="false" />
        <Property Name="IsDone" Type="Edm.Boolean" />
        <NavigationProperty Name="TodoList" Relationship="ODataBreezejsSample.Models.ODataBreezejsSample_Models_TodoItem_TodoList_ODataBreezejsSample_Models_TodoList_TodoListPartner" ToRole="TodoList" FromRole="TodoListPartner" />
      </EntityType>
      <EntityType Name="TodoList">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
        <Property Name="Title" Type="Edm.String" Nullable="false" />
        <Property Name="Created" Type="Edm.DateTime" Nullable="false" />
        <NavigationProperty Name="TodoItems" Relationship="ODataBreezejsSample.Models.ODataBreezejsSample_Models_TodoList_TodoItems_ODataBreezejsSample_Models_TodoItem_TodoItemsPartner" ToRole="TodoItems" FromRole="TodoItemsPartner" />
      </EntityType>
      <Association Name="ODataBreezejsSample_Models_TodoItem_TodoList_ODataBreezejsSample_Models_TodoList_TodoListPartner">
        <End Type="ODataBreezejsSample.Models.TodoList" Role="TodoList" Multiplicity="0..1" />
        <End Type="ODataBreezejsSample.Models.TodoItem" Role="TodoListPartner" Multiplicity="0..1" />
      </Association>
      <Association Name="ODataBreezejsSample_Models_TodoList_TodoItems_ODataBreezejsSample_Models_TodoItem_TodoItemsPartner">
        <End Type="ODataBreezejsSample.Models.TodoItem" Role="TodoItems" Multiplicity="*" />
        <End Type="ODataBreezejsSample.Models.TodoList" Role="TodoItemsPartner" Multiplicity="0..1" />
      </Association>
      <EntityContainer Name="TodoListContext" m:IsDefaultEntityContainer="true">
        <EntitySet Name="TodoItems" EntityType="ODataBreezejsSample.Models.TodoItem" />
        <EntitySet Name="TodoLists" EntityType="ODataBreezejsSample.Models.TodoList" />
        <AssociationSet Name="ODataBreezejsSample_Models_TodoItem_TodoList_ODataBreezejsSample_Models_TodoList_TodoListPartnerSet" Association="ODataBreezejsSample.Models.ODataBreezejsSample_Models_TodoItem_TodoList_ODataBreezejsSample_Models_TodoList_TodoListPartner">
          <End Role="TodoListPartner" EntitySet="TodoItems" />
          <End Role="TodoList" EntitySet="TodoLists" />
        </AssociationSet>
        <AssociationSet Name="ODataBreezejsSample_Models_TodoList_TodoItems_ODataBreezejsSample_Models_TodoItem_TodoItemsPartnerSet" Association="ODataBreezejsSample.Models.ODataBreezejsSample_Models_TodoList_TodoItems_ODataBreezejsSample_Models_TodoItem_TodoItemsPartner">
          <End Role="TodoItemsPartner" EntitySet="TodoLists" />
          <End Role="TodoItems" EntitySet="TodoItems" />
        </AssociationSet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

The workaround is to generate the $metadata from the EF edmx.

Regression reminder: Ensure that the ODataClient continues to work after this metadata change.

johncrim commented 9 years ago

Fixed in 0.9.0