views:

33

answers:

2

I am trying to create a LINQ query to return genres by movieid. The LINQ works in LINQPAD4. Can someone help me with the proper syntax? I am getting the following errors:

Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)

and

Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'

Code:(note I have wrapped Title in the following line with parenthesis, but are actually brackets in my code.

public List(Genre) GetGenresByMovieId(string movieid)
{
var genres = from t in MovieCatalog.Titles
where t.Id == "BVlLx"
select t.Genres; return genres.ToList();
}

A: 

Your problem is your projection:

select new { Name = g.Name }

That is projecting the query into an anonymous type.

You need to project into the IQueryable you have declared (IQueryable<Genre>)

When working with LINQ queries, it's preferable to use implicitly-typed variables (var).

Also, not sure why you have that extra "from" in your query, you don't need that.

Something like this should work:

var genres = from t in MovieCatalog.Titles
             where t.Id = "BVlLx"
             select t.Genres;

return genres.ToList();

var genres should be typed to an IQueryable<Genre>.

That is assuming you want to return a collection of Genre objects.

If you just want the name, do this:

select t.Genres.Name

But that will return a collection of string objects (and var genres should be typed to an IQueryable<string>).

However, i have no idea about the NetFlix OData API, but that should get you on the right track.

RPM1984
Thanks. I am not getting this error: Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.ObjectModel.Collection<Netflix.ODataNetflixService.Genre>>' to 'System.Collections.Generic.List<Netflix.ODataNetflixService.Genre>'
obautista
@obautista - because of your method signature (you expect a return type of `List<Title>`). What do you want returned? A collection of Genres, or a collection of Genre names?
RPM1984
I realized that after I posted. I edited my post to reflect using List<Genre>. I tried the LINQ suggested in LINQPAD4 and that returns "The method 'Select' is not supported". This may be the reason for the anonymous type. My last comment reflects using List<Genre>.
obautista
@obautista - can you edit your question to show what code you currently have? im not too concerned with LinqPad right now, just with your LINQ code. When i said "if you just want the name, do this..", i meant INSTEAD of the `select t.Genres`, not on it's own. That's why you go the LinqPad error.
RPM1984
This generates the error above: public List<Genre> GetGenresByMovieId(string movieid){ var genres = from t in MovieCatalog.Titles where t.Id == "BVlLx" select t.Genres; return genres.ToList();}
obautista
which error? the "Select" is not supported, or one of the others. This is why i said - edit your question, don't put code in comments here, it's just making it more difficult.
RPM1984
Sorry about that. Just edited my code in the question to reflect the LINQ I am using.
obautista
It's hard to tell you which code to use, because i don't know the OData API. That LINQ query is correct. The only thing that is incorrect is either what you are projecting into, or your method signature. When you hover over `t.Genres`, what does it say the type is? `IQueryable<Genre>`?
RPM1984
I get this: System.Collections.ObjectModel.Collection<Genre> Title.Genres. Note, Genres is a collection inside Titles. I need to get at the Genres collection to get the Name property inside Genres. A Title holds onto a collection of Genres. I need to pull the collection of Genres for a particular title.
obautista
Yes - i understand Genres is a collection inside Titles. I didn't know it was of type `ObjectModel.Collection<Genre>`. Your method signature should be `Collection<Genre>` then, not `List<Genre>`
RPM1984
Okay. What would I return? Returning this: return genres.ToList(); throws this exception: Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.ObjectModel.Collection<Netflix.ODataNetflixService.Genre>>' to 'System.Collections.ObjectModel.Collection<Netflix.ODataNetflixService.Genre>'
obautista
if you're saying `Title.Genres` is already an `ObjectModel.Collection<Genre>` then you don't need the `.ToList()`. Just `return genres`.
RPM1984
Sorry, but that returns this: Cannot implicitly convert type 'System.Linq.IQueryable<System.Collections.ObjectModel.Collection<Netflix.ODataNetflixService.Genre>>' to 'System.Collections.ObjectModel.Collection<Netflix.ODataNetflixService.Genre>'. An explicit conversion exists (are you missing a cast?)
obautista
A: 

The right query would look like

public IEnumerable<Genre> GetGenresByMovieId(string movieId)
{
    return from title in ctx.Titles
           from genre in title.Genres
           where title.Id == "BVlLx"
           select genre;
}

In the method call syntax, you need to use SelectMany, not Select, since the filter on titles returns a list of titles (which will always contain just one title, but the compiler doesn't know that) and so you want to "concatenate" all genres for each title in the results.

The return type is actually IQueryable, but if you only plan to enumerate over it, you can use IEnumerable, or call ToList() to force execution right there in the method (the way I wrote it the query would actually execute only once you try to enumerate it).

Vitek Karas MSFT
Thank you. I am trying to bind the result set to a data control (i.e. Repeater). Will this work: rpt.datasource = GetGenresByMovieId("BVlLx"); rpt.DataBind(); I do not understand your comment about SelectMany.
obautista
Forgot to mention. In markup page I want to display only the Genre Names for the Movie Title, so something like this: <asp:rpt><itemtemplate><%# EVAL("Name") %></itemtemplate></asp:rpt>. I abbreviated the code a little.
obautista
Sorry I don't know enough about ASP.NET to answer this question. The method simply returns enumeration of Genre objects.
Vitek Karas MSFT
If you use the syntax above, you don't have to care about SelectMany (that's what C# compiler translates the above code into).
Vitek Karas MSFT