7

I've read both these articles multiple times to try and figure out a way to use the $expand query option on a single entity, but in each and every way I've tried, I just can't seem to be able to make it work. All the other query options work and $expand also currently works on collection results.

Model: Player entities have a navigation property called Stats in which each object contains the stats for that player for a given year.

I've set up OData this way:

config.EnableQuerySupport();

ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Player>("OPlayer");
modelBuilder.EntitySet<PlayerStatistics>("OPlayerStats");

Microsoft.Data.Edm.IEdmModel model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute("ODataRoute", "odata", model);

Originally, I had set up my controller this way:

public class OPlayerController : EntitySetController<Player, int>
{
    private readonly DatabaseContext _db = new DatabaseContext();

    protected override Player GetEntityByKey(int key)
    {
        return _db.Players.FirstOrDefault(p => p.PlayerId == key);
    }

    public override IQueryable<Player> Get()
    {
        return _db.Players.AsQueryable();
    }

    protected override void Dispose(bool disposing)
    {
        _db.Dispose();
        base.Dispose(disposing);
    }
}

With this configuration, I can make these queries:

  • /odata/OPlayer(600)
  • /odata/OPlayer
  • /odata/OPlayer?$expand=Stats

But evidently not (the result is not expanded):

  • /odata/OPlayer(600)?$expand=Stats

Both articles mention that in order to support it, you have to add a method (action?) to your controller that looks like this:

[Queryable]
public SingleResult<Player> GetPlayer(int id)
{
    return SingleResult.Create(_dbContext.Players.Where(c => c.ID == id);
}

When I add this to my controller though, both /odata/OPlayer(600) and /odata/OPlayer(600)?$expand=Stats return No action was found on the controller 'OPlayer' that matches the request.

Can anyone provide clarifications, or give pointers in order to support $expand on a single entity?

Gabriel G. Roy
  • 2,552
  • 2
  • 27
  • 39

1 Answers1

5

Your action GetPlayer got the parameter name incorrect. The parameter name should be "key" instead of id. Try this as your action instead,

[Queryable]
public SingleResult<Player> GetPlayer([FromODataUri]int key)
{
    return SingleResult.Create(_db.Players.Where(c => c.PlayerId == key));
}
RaghuRam Nadiminti
  • 6,718
  • 1
  • 33
  • 30
  • Ahh, I did miss the following [article](http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions) which clearly states that the parameter must be called key! Thanks for that. I'm still getting the following error though: `The given model does not contain the type 'System.Web.Http.SingleResult[PolyPoolBasic.Models.Player].` – Gabriel G. Roy Oct 02 '13 at 20:24
  • Seems like this might have been fixed in a more recent version, I'm gonna try with the nightly build – Gabriel G. Roy Oct 02 '13 at 20:46
  • Confirmed! Updated both Web API and Web API OData to 5.1.0-alpha1 and everything works fine! – Gabriel G. Roy Oct 02 '13 at 21:01
  • yeah, we regressed that in RC release. we fixed it for 5.0.0 RTM release though which should be out soon. – RaghuRam Nadiminti Oct 04 '13 at 00:31