2010-11-20 25 views
0

J'ai un C# -4 test de l'application MVC3 RC qui utilise Entity Framework 4.EF4 Linq type de retour de liste générique

J'ai cette méthode:

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

Les objets impliqués ici (contenu et Site Web) sont de type EntityObject.

La fonction ci-dessus donne une erreur de compilation:

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 est une collection de type EntityCollection<Content>. Comment puis-je reporter le type Linq.IQueryable pour retourner une liste générique de type Content?

Répondre

2

Vous devez utiliser des parenthèses, de sorte que vous appliquez ToList() à toute requête (un objet de type IQueryable):

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

Sinon, vous appellent ToList() sur w.Contents seulement et le select est appliqué par la suite. Il pourrait être plus clair si je montre la syntaxe de chaînage de la méthode.

Votre version:

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

Version correcte:

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

Modifier:

Depuis w.Contents est une collection, vous devez l'aplatir en utilisant SelectMany:

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

je en effet oublié la parenthèse, mais il donne encore une autre erreur de conversion: ne peut pas convertir implicitement le type « System.Collections.Generic.List > 'à' System.Collections.Generic.List ' – peter

0

Le .First() semble faire l'affaire ... merci.

+1

En utilisant d'abord, vous ne sélectionnerez qu'un élément de chaque collection 'Contents' (pour chaque site Web). Pour obtenir tous les éléments, utilisez 'SelectMany'. Voir ma mise à jour post. – Yakimych

+0

C'est ce que je pensais aussi, mais .First() sélectionne également tous les éléments. Je pense que cela signifie qu'il va sélectionner la première collection, qui contient tous les éléments de contenu. – peter

0

Yakimych's answer en utilisant SelectMany() est corret. Pour être complet, ici, il utilise « la compréhension de la requête » syntaxe:

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