any word on when $expand support might be coming?

Topics: ASP.NET Web API
Oct 9, 2012 at 9:05 AM


I'm simply curious when the expand functionality might see the light or should I just start implementing it myself?


Oct 9, 2012 at 4:19 PM
Edited Oct 9, 2012 at 9:15 PM

Most likely we won't get to $expand until next year.

Daniel Roth

Oct 9, 2012 at 8:51 PM
danroth27 wrote:

Most likely we want get to $expect until next year.

Daniel Roth

How about support for returning already expanded object, for example i need something like this:

return repository.Product.Include("Category");

Is there support for returning inline Category data together with a Product?


Oct 9, 2012 at 9:15 PM

Yikes! Sorry about my typos. Corrected above. That should have read:

Most likely we won't get to $expand until next year.

Daniel Roth

Oct 27, 2012 at 5:03 PM

$expand and $select are available in breeze.js today

Jan 22, 2013 at 4:18 PM

What's the current roadmap look like for this? Alternatively, any broad suggestions about how it might be implemented?

Jan 22, 2013 at 7:41 PM

No specific timeframe yet, but it most likely won't show up for at least a couple of months.

Daniel Roth

May 8, 2013 at 7:00 PM
$expand is already supported by the current version???
May 8, 2013 at 7:08 PM
Yes. $select and $expand support is available in the nightly builds. Instructions on using our nightly builds are here -
May 8, 2013 at 7:16 PM
Thanks a lot
May 8, 2013 at 8:19 PM
Edited May 8, 2013 at 8:22 PM
Other problem :). Apparently not support inlinecount with Expanded


Only a top-level feed can have the 'ODataFeed.Count' property value specified. Expanded links do not support inline counts.
In my case I have the entity Company with a list of phone numbers, addresses and emails.

In query need to load companies with phones and emails to display in a paged table (20 items per page).
public class Company : Entidade
    public string Name{ get; set; }
    public virtual Pessoa Contact { get; set; }

    public virtual ICollection<Phone> Phones { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Email> Emails { get; set; }
May 8, 2013 at 10:42 PM
Thanks for reporting this. This is a bug. I have opened this issue to track it
Apr 26 at 7:33 PM
I have a Web API ApiController method that's returning a PageResult<T> and accepts a ODataQueryOptions<T> parameter. This works fine with $inlinecount=allpages until I add $expand to my query, which throws an InvalidCastException. When I include the private methods from sample 4 - "Supporting $select and $expand with ODataQueryOptions<T>" - on the $select and $expand support wiki page, I get the same successful result including the count when I don't include $expand, but the response is null when I include $expand.

I was wondering if this scenario of using $inlinecount and $expand is currently supported, or if there's something else I may need to tweak that would return the expanded result including the count.
Apr 29 at 7:42 AM
I've just picked up on this myself and I'm certain it's a bug in the current implementation.

It isn't related to $inlinecount at all, simply to the use of $expand WHEN ODataQueryOptions are passed into the controller (ie NOT when the GET method is simply marked as [Queryable]).

Put simply the method ODataQueryOptions<T>.ApplyTo() returns null EVERY TIME an Expand/Select clause is part of the query options, instead of returning an IQueryable<T>. All other query options return IQueryable<T> (until expand/select is added).

I'm going to post this as a new thread here in the hope that it is flagged as a bug and resolved...
Apr 30 at 7:11 PM
Go ahead and open a bug in our issues tracker with the steps to reproduce the issue and we will take a look.

Daniel Roth
Apr 30 at 11:06 PM
May 1 at 2:54 PM
Edited May 1 at 3:06 PM
This kind of question has been asked numerous times before, but this is definitely not an issue, I'm afraid: $expand and $select internally use the LINQ Select method to project the entities to specific property containers (e.g SelectExpandWrapper) just like you'd do in a classic LINQ query with an anonymous type:
public class Entity {
    public int Id { get; set; }
    public string Name { get; set; }

var array = new[] { new Entity { Id = 1, Name = "Your entity" } };
var projection = from entity in array.AsQueryable()
                 select new { Name = entity.Name };
As a consequence, the return type of the LINQ query is not IQueryable<Entity> nor IEnumerable<Entity> anymore, but an IQueryable<T> in which the generic type T is automatically created and determined by the compiler (that's why you need to use var here). If you're not convinced, create a new console app', add a new LINQ query using some projection in the Main method and use .NET reflector or ILSpy - make sure to disable advanced decompilation options in View/Options to see how this works behind the scenes.

Similarly, Web API OData use internal artifacts (notably the SelectExpandWrapper and SelectExpandWrapperConverter classes) to support projection and serialization of projected entities: when you call the ApplyTo method with a $select or $expand clause, its return type cannot be IQueryable<DataObject> and that's why options.ApplyTo(db.DataObjects) as IQueryable<DataObject> returns null.

Take a look at this great post to see how this works and the possible "workarounds" (point 4 and "generated queries" part) :
May 1 at 11:16 PM
Awesome, makes a LOT more sense to me now! I guess the main problem for those of us who just want to 'use' this capability is that the examples in blogs, etc are all at a VERY simple level and don't tend to flag these types of issues (ie how do you support both /$count and ?$expand with the same controller... maybe you don't or maybe you can use the workaround you've pointed out in the spec documentation).