Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Lambda query 'select' not working with oData

Tags:

c#

linq

odata

I'm currently trying to understand some of the fundamentals with LINQ. I have been using LINQPad to query the Netflix OData source.

Source: http://odata.netflix.com/v2/Catalog/

I can't seem to select single properties when using a lambda query - the comprehension query works perfectly. I found a snippet of code that performs a more complex query using lambdas on the Netflix oData source, and this seems to work fine for returning one property of the entity.

// works fine
var compQuery = from t in Titles
                where t.ReleaseYear == 2007
                select new { t.Name };
compQuery.Dump();   



// fails: "Can only specify query options (orderby, where, take, skip) after last navigation."
var lambdaQuery = Titles
            .Where(t => t.ReleaseYear == 2007)
            .Select(t => t.Name);

lambdaQuery.Dump(); 


// works fine - found on SO.
var lambdaQuery2 = People
    .Expand("TitlesActedIn")
    .Where(p => p.Name == "George Lucas")
    .First()
    .TitlesActedIn.Select(t => t.ShortName);              

lambdaQuery2.Dump(); 

Could anyone shed some light as to why the basic lambda query is failing when asked to return one property?

like image 212
Dalbir Singh Avatar asked Mar 14 '12 20:03

Dalbir Singh


3 Answers

OData doesn't have support for projecting to properties - you can work around this though:

var lambdaQuery = Titles
            .Where(t => t.ReleaseYear == 2007)
            .Select(x=> new { x.Name })
            .AsEnumerable()
            .Select(t => t.Name);

Using AsEnumerable() forces the last part of the query to be executed in Linq-to-Objects context (instead of an OData query) where the projection works just fine.

like image 138
BrokenGlass Avatar answered Nov 10 '22 07:11

BrokenGlass


Try this- it is what is actually equivalent to your first one:

// fails: "Can only specify query options (orderby, where, take, skip) after last navigation."
var lambdaQuery = Titles
            .Where(t => t.ReleaseYear == 2007)
            .Select(t => new { t.Name });

lambdaQuery.Dump(); 
like image 37
Chris Shain Avatar answered Nov 10 '22 07:11

Chris Shain


Using the answers given, I have ran some tests and found some interesting things regarding execution time:

// Avg Execution Time: 5 seconds
var query1 = Titles
            .Where(t => t.ReleaseYear == 2007)
            .Select(t => new {t.Name});     
query1.Dump();


// Avg Execution Time: 15 seconds
var query2 = Titles
            .Where(t => t.ReleaseYear == 2007)
            .AsEnumerable()
            .Select(t => t.Name);       
query2.Dump();

So am I right in thinking that in query 1, only the 'Name' property is being returned? Whereas in query 2, the 'AsEnumerable()' method is bringing back the entity with all property values, hence longer execution time?

like image 33
Dalbir Singh Avatar answered Nov 10 '22 07:11

Dalbir Singh