2010-11-20 3 views
0

У меня есть C# -4 MVC3 RC тест-приложение, которое использует Entity Framework 4.EF4 Linq типа возвращаемого родовой список

У меня есть этот метод:

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

Объекты, участвующих здесь (содержание и Веб-сайт) имеют тип EntityObject.

выше функция дает ошибку компиляции:

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 является коллекция EntityCollection<Content> типа.

Как отменить тип Linq.IQueryable, чтобы вернуть общий список типов содержимого?

ответ

2

Вы должны использовать круглые скобки, так что вы применяете ToList() на весь запрос (объект типа IQueryable):

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

В противном случае вы звоните ToList() на только w.Contentsselect и применяется впоследствии. Может быть, яснее, если я покажу синтаксис цепочки метода.

Ваша версия:

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

Правильная версия:

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

Edit:

Поскольку w.Contents коллекция, вам нужно, чтобы сгладить его с помощью SelectMany:

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

Я действительно забыл скобку, но она по-прежнему дает другую ошибку преобразования: Не удается неявно преобразовать тип «System.Collections.Generic.List > 'to' System.Collections.Generic.List ' – peter

0

. Первый(), кажется, делает трюк ... спасибо.

+1

При первом использовании вы будете выбирать только один элемент из каждой коллекции 'Contents' (для каждого сайта). Чтобы получить все предметы, используйте 'SelectMany'. См. Мое обновленное сообщение. – Yakimych

+0

Вот что я тоже подумал, но .First() также выбирает все элементы. Я думаю, это означает, что он выберет первую коллекцию, содержащую все элементы контента. – peter

0

Yakimych's answer используя SelectMany() - это корень. Для полноты картины, здесь используется «запрос» на слух синтаксис:

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(); 
} 
Смежные вопросы