Alex
Alex

Reputation: 3470

Is it possible to have multiple controllers for a single entity type?

I have an entity framework model. Let's say we have an object Foo and an object Bar. They are related, so Foo has a navigation property to Bar, and vice versa.

Now, for my OData endpoint, I'd like to have two collections available for Foo, for instance declared like so:

var builder = new ODataConventionModelBuilder { Namespace = "Test" };
builder.EntitySet<Foo>("Fools");
builder.EntitySet<Foo>("Footballs");
builder.EntitySet<Bar>("Bars");

The idea here is that access to Fools would go through the FoolsController and access to Footballs would go through the FootballsController, so that I could return different sets of data in each endpoint.

Trying to do this, however, causes the following NotSupportedException error message:

Cannot automatically bind the navigation property 'FooThing' on entity type 'Foo' for the entity set or singleton 'Bars' because there are two or more matching target entity sets or singletons. The matching entity sets or singletons are: Fools, Footballs.

I sort of understand the issue, but if I know for a fact that only Footballs will have Bars, is there a way for me to help the system understand that Bars will only have Footballs?

Upvotes: 2

Views: 1627

Answers (1)

Sam Xu
Sam Xu

Reputation: 3380

The answer is absolutely yes. There are many fluent APIs that you can call to set the binding manually, then to suppress the convention binding. For example:

HasManyBinding
HasRequiredBinding
HasOptionalBinding
HasSingletonBinding
...

Based on your information, you can call the following to make the binding manually:

builder.EntitySet<Bar>("Bars").HasRequiredBinding(b => b.FooThing, "Fools");

I also create a simple Foo and Bar class model to test. The below result shows the metadata:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="WebApiTest" xmlns="http://docs.oasis-open.org/odata/ns/ed
m">
      <EntityType Name="Foo">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
      </EntityType>
      <EntityType Name="Bar">
        <Key>
          <PropertyRef Name="Id" />
        </Key>
        <Property Name="Id" Type="Edm.Int32" Nullable="false" />
        <NavigationProperty Name="FooThing" Type="WebApiTest.Foo" Nullable="fals
e" />
      </EntityType>
    </Schema>
    <Schema Namespace="Test" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityContainer Name="Container">
        <EntitySet Name="Fools" EntityType="WebApiTest.Foo" />
        <EntitySet Name="Footballs" EntityType="WebApiTest.Foo" />
        <EntitySet Name="Bars" EntityType="WebApiTest.Bar">
          <NavigationPropertyBinding Path="FooThing" Target="Fools" />
        </EntitySet>
      </EntityContainer>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

As you can see, "HasRequiredBinding" can make the navigation property as non-nullable, while, "HasOptionBinding" can make it nullable.

Hope it can help. Thanks.

Upvotes: 4

Related Questions