peter
peter

Reputation: 3

EF4 Linq return type generic list

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?

Upvotes: 0

Views: 964

Answers (3)

Lucas
Lucas

Reputation: 17424

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();
}

Upvotes: 0

Yakimych
Yakimych

Reputation: 17752

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();
}

Upvotes: 2

peter
peter

Reputation: 3

    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.

Upvotes: 0

Related Questions