Reputation: 3470
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
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