WebAPI ODATA v3 can only generate uni-directional associations

This will be a quick post about WebAPI and ODATA controllers, and a strange “bug” or behaviour I found. I was not aware of this, so maybe it is also of some interest for you. When you create an ODATA service via WebAPI and want to connect two or more entity sets via a relation the standard example will tell you to define your models somehow similar to this (see also Mike Wasson and his post Supporting Entity Relations in OData v3 with Web API 2 :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace bizdfchApplication.Models
  public class Task
    public int Id { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTimeOffset Created { get; set; }
    public DateTimeOffset Modified { get; set; }
    public DateTimeOffset Due { get; set; }

    public int TenantId { get; set; }
    public Tenant Tenant { get; set; }

  public class Tenant
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }

    public List<Task> Tasks { get; set; }

This would and will define a relationship where a Tenant can have multiple Tasks and a Task can only have one Tenant. When you look at the generated $metadata you will notice that your relationship (or navigationproperty in ODATA terms) is expressed not via one Association but actually via _two_ distinct Associations. One Association into each direction. This is strange, as both Associations express the correc relationship (from their point of view). This is actually nuisance as this would mean you would have to code the relationship manually twice when creating, updating and deleting your entities.

Further investigation on ASP.net and stackoverflow showed that this is actually known and will not be fixed, as you can read in the following posts:

  1. Two distinct associations instead of one
  2. OData model builder should reuse association for bi-direction navigation properties
  3. Missing inverse property in asp.net webapi odata $metadata

The story behind is that in ODATA v4 the navigation properties will not have associations any more (as far as I understood the examples in the preliminary ODATA v4 spec). Still a nusiance when dealing with WebAPI ODATA v3 – much more manual coding and much space for inconsistencies as you have no atomic way to update both sides of the relationship.


  1. Reblogged this on Dinesh Ram Kali..

  2. Mike DiSibio says:

    Since Lightswitch only accepts v3 for now, this behavior breaks Lightswitch. Even though you create v3 libraries, the ODataModelBuilder produces two associations. One of them is “0..1 to 0..1” and Lightswitch will throw those out. Thus, any screens in LS treat the data model has having one-way relationships only…and this is corraborated by the lsml files.

    Thanks so much for writing this up. I’m sure you felt “nobody cares” but I’ve been beating my head against this for the past two weeks. I’m frustrated that the same exact Edm model will will work for LS to database but not LS to OData.

  3. Ronald Rink says:

    I once had a quick look on how the generate the EDM manually but voted against it, as it first did not seem to be supported, plus I would have to override it on every rebuild and I then still would not be sure if the generated javascript model would support this.
    As LightSwitch does not seem to get much attention from Microsoft lately I instead opted to use ODATAv4 and the jaydata client library (without LightSwitch generated entities).
    I am a bit disappointed by the evolution of LightSwitch and will not invest into too much LightSwitch specific stuff. Sorry I am of no help here.

  4. Oliver says:

    Thanks Ronald and joshbooker so much for sharing! Pretty helped me to get a running solution.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: