3
votes

I'm querying my service using a url like:

http://a.com:3080/odata/DiscussionVM(6)?$expand=Section,User

on controller method:

[EnableQuery(MaxExpansionDepth = 7)]
        public SingleResult<DiscussionVM> GetDiscussionVM([FromODataUri] int key)
        {
            return SingleResult.Create(db.DiscussionVMs.Where(discussionVM => discussionVM.DiscussionId == key));
        }

This works and returns the correct JSON.

However I then run the slightly more advanced query on a different model:

http://a.com:3080/odata/OrganisationVM(30)?&$expand=Categories($expand=Discussions($expand=Section,User))

and controller action:

// GET: odata/OrganisationVM(5)
        [EnableQuery(MaxExpansionDepth = 5, AllowedQueryOptions = AllowedQueryOptions.All)]
        public SingleResult<OrganisationVM> Get([FromODataUri] int key)
        {
            return SingleResult.Create(db.OrganisationVMs.Where(organisationVM => organisationVM.OrganisationId == key));
        }

this returns the below DiscussionVM JSON:

{
@odata.type: "#Models.DiscussionVM",
DiscussionId: 6,
Section_SectionID: 1005,
User_Id: "4cecc52e-ac3a-4696-ac6c-175af2a6378a",
DateCreated: "2014-12-06T00:00:00Z",
OrgCat_OrganisationCategoryId: 1,
Text: "Dummy section",
Html: null,
IsUserCreated: true,
Organisation_OrganisationId: null,
Positives: null,
Negatives: null,
CommentCount: 1
}

But contains no User or Section object. No error is thrown. The correct objects are queried (profiled) in the database and data including user and section are returned.

3
It's been a while, any update on this?Jerther
Nope :/. I ended up adding an extra webApi call.chris stevens
Sigh I guess I'll return a JSON string for now.Jerther
$expand=Categories($expand=Discussions($expand=Section,User($select=BLAH))) would throw an error stating User has no such property, and $expand=Categories($expand=Discussions($expand=Section,User($select=FirstName))) would succeed but the result would still have no User or Section. Deep inspection of the odata query parameters in the method shows that all expand options are present. This looks more and more like a problem with the serialization.Jerther

3 Answers

2
votes

I discovred that oData needs the expanded entities to be referenced in its Edm Model. if not it will stop expanding after the first level, that's why further expands will not work.

Just add your expandable EntitySet to the ODataConventionModelBuilder in your IEdmModel (in MapODataServiceRoute's model config) :

var builder = new ODataConventionModelBuilder();
// ...
builder.EntitySet<Categories>("categories");
// ...

Hope this helps.

0
votes

I have never seen your $expand syntax before. Where did you get it from? I think you must expand your query the following way:

http://a.com:3080/odata/OrganisationVM(30)?$expand=Categories/Discussions/Section,Categories/Discussions/User

Assuming Odata V4, here are some examples of the standard.

0
votes

From what Brad and I have gathered in this SO answer, it could be a matter of mixing complex types with entity types. Expand plays very well if all your types are entities, but if you mix both, you end up with weird behavior like you and I are having.

If you do mix them, the expand cascade has to start with entity types and end with complex types. The expand chain seems to end where a complex type has an entity type property.

This could come from v3 where a complex type referring to an entity type was flat not supported. It is in V4 but it is not totally clean with WebAPI as we can see.

The lack of documentation and support on the matter makes it difficult to claim this is the absolute truth, but at least it explained my situation and made my stuff work. Hope it helps you too.