Search code examples
c#odata

OData with multiple keys


I'm using the Microsoft.OData 6.11.0 package, and I'd like to be able to allow users of the API to use one of three properties (DB primary key, username, or external ID number) as the key for a data type representing people. The formats for the properties are different enough that they can be distinguished between easily. I set up the OData model as follows:

ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Person>("Person");
config.MapODataServiceRoute(
    routeName: "ODataRoute",
    routePrefix: "OData",
    model: builder.GetEdmModel());

In the controller, I have:

[EnableQuery]
public SingleResult<Person> Get([FromODataUri] String key) {/*...*/}

[EnableQuery(PageSize = 100)]
public IQueryable<Widget> WidgetsFromPerson([FromODataUri] String key) {/*...*/}

which takes a guess at which identifier is provided and returns the appropriate data. These work:

GET http://localhost/app/OData/Person(1234)
GET http://localhost/app/OData/Person(999999999)
GET http://localhost/app/OData/Person(1234)/Widgets
GET http://localhost/app/OData/Person(999999999)/Widgets

These get me a 404.

GET http://localhost/app/OData/Person('username')
GET http://localhost/app/OData/Person('username')/Widgets

If I can't do this, is there an alternate syntax I can use to get the person by username as well as the widgets for that person by username?

The metadata returned through the API includes this:

<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="MyModel" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="AbstractPerson" Abstract="true">
        <Key>
          <PropertyRef Name="PersonId" />
        </Key>
        <Property Name="PersonId" Type="Edm.Int32" Nullable="false" />
      </EntityType>
      <EntityType Name="Person" BaseType="MyModel.Person">
        <Property Name="UserName" Type="Edm.String" />
        <NavigationProperty Name="Widgets" Type="Collection(MyModel.Widget)" />
      </EntityType>
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>

Thanks!


Solution

  • I do think what you're looking for is a feature similar to alternate key.

    OData team is working on alternate key supporting. You can find the detail information and sample from here

    Besides, you can find the implementation in progress.