Question

I have a C#-4 MVC3 RC test-application which is using Entity Framework 4.

I have this method:

public static List<Content> FetchMenu(int websiteID) {
    return (from w in ContextHelper.Current.Websites
            where w.WebsiteID == websiteID
            select w.Contents).ToList();
}

The objects involved here (Content and Website) are of type EntityObject.

The above function gives compilation error:

Cannot implicitly convert type 'System.Linq.IQueryable<System.Collections.Generic.List<Manager.Models.Content>>' to 'System.Collections.Generic.List<Manager.Models.Content>'. An explicit conversion exists (are you missing a cast?)

w.Contents is an EntityCollection<Content> type collection.

How do I defer the Linq.IQueryable type to return a generic List of type Content?

Was it helpful?

Solution

You need to use parentheses, so that you apply ToList() to the whole query (an object of type IQueryable):

public static List<Content> FetchMenu(int websiteID) {
    return (from w in ContextHelper.Current.Websites
            where w.WebsiteID == websiteID
            select w.Contents).ToList();
}

Otherwise you are calling ToList() on w.Contents only and the select is applied afterwards. It might be clearer if I show the method chaining syntax.

Your version:

ContextHelper.
           Current.
           Websites.
           Where(w => w.WebsiteID == websiteID).
           Select(w => w.Contents.ToList());

Correct version:

ContextHelper.
           Current.
           Websites.
           Where(w => w.WebsiteID == websiteID).
           Select(w => w.Contents).
           ToList();

Edit:

Since w.Contents is a collection, you need to flatten it out by using SelectMany:

public static List<Content> FetchMenu(int websiteID) {
    return ContextHelper.
           Current.
           Websites.
           Where(w => w.WebsiteID == websiteID).
           SelectMany(w => w.Contents).
           ToList();
}

OTHER TIPS

    var query = (from w in ContextHelper.Current.Websites
                 where w.WebsiteID == websiteID
                 select w.Contents).First();

    return query.ToList();

The .First() seems to do the trick... thanks.

Yakimych's answer using SelectMany() is corret. For completeness, here it is using "query comprehension" syntax:

public static List<Content> FetchMenu(int websiteID) {
    return (from w in ContextHelper.Current.Websites
            where w.WebsiteID == websiteID
            from c in w.Contents
            select c).ToList();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top