Expand in a Projection (Select) for WCF Data Services (OData)

You don't have to create a sub-projection which lists out all 46 attributes, e.g.

(from u in Users
 select new 
    {
    u.Id, u.Reputation,Comments = ( from c in u.Comments 
                                    select new YourClass {comment = c, 
                                                          post= c.Post})
    }
)
.Take(10)


.....


public Class YourClass
    {
    public Comment comment {get;  set;}
    public Post post {get;set;}
    }

Not exactly the object graph I imagine you're after.

This aside, one can spend a lot of time trying to write a LinQ expression that will generate the correct OData query, we've found that it is much more time effecient to create your own OData query class with Expand, Filter, Select properties etc. i.e. go straight to writing OData queries instead of trying to craft LinQ queries.


You can do,

Users.Take(10).Select(x=>new { Id = x.Id, Reputation = x.Reputation, Comments = x.Comments.Select(c =>c.Id) })

That would result in the request,

https://data.stackexchange.com/stackoverflow/atom/Users()?$top=10&$expand=Comments&$select=Id,Reputation,Comments/Id


It is certainly possible to do that. For a proof of concept try executing this:

var uri = new Uri( "http://data.stackexchange.com/stackoverflow/atom/Users()?$top=10&$expand=Comments/Post&$select=Id,Reputation,Comments/" );
entities.Execute<User>( uri, "GET", false ).Select( x => new { x.Id, x.Reputation, x.Comments } );

The correct usage of expand is like this:

entities.Users.Expand( "Comments/Post" ).Take( 10 ).ToArray();

I don't know why the writers of the library have decided to disallow using expand with projections, but as the above proof of concept shows, it is certainly possible to do so.

If you don't mind receiving the entire user and making the projection after that, you can go with the second example. Else you can write your own helpers which will produce the URI from the first example, execute them, and add the projection after that.