2011-08-16 3 views
0

Ce n'est pas la première fois que je suis coincé sur des collections. Il me manque quelque chose ici et je ne me sens pas seulement un peu frustré. Cet extrait de code est conçu pour renvoyer le nombre de "critiques de restaurant" dans la base de données REVIEW ayant un "identifiant de restaurant" spécifié. Encore une fois je reçois le un "ne peut pas implicitement caché type" erreur.Impossible de convertir le type

Merci d'avance!

public IEnumerable<string> getNumReviews(int RestID) 
    { 
     var NumReviews = from REVIEW in db.REVIEWs 
         where REVIEW.REST_ID == RestID 
         group REVIEW by REVIEW.REVIEW_ID into t 
         select new { REVIEW_ID = t.Key, TagCount = t.Count() }; 
     return NumReviews; 
    } 
+0

Votre méthode a un type de retour de IEnumerable encore votre instruction select crée un nouvel objet anonyme avec 2 propriétés. –

Répondre

1

NumReviews est un IEnumerable<anonymous type>, et non IEnumerable<string>. En particulier, vous conservez une énumération d'objets comprenant un REVIEW_IDet un le nombre de tags pour chaque révision.

Votre meilleure option est de déclarer un type d'encapsuler cette information:

public class NumReviewInfo 
{ 
    public int ReviewId { get; set; } 
    public int NumTags { get; set; } 
} 

Ensuite, sélectionnez l'objet à partir de la méthode:

public IEnumerable<NumReviewsInfo> getNumReviews(int RestID) 
{ 
    var NumReviews = from REVIEW in db.REVIEWs 
        where REVIEW.REST_ID == RestID 
        group REVIEW by REVIEW.REVIEW_ID into t 
        select new NumReviewsInfo { ReviewId = t.Key, NumTags = t.Count() }; 
    return NumReviews; 
} 
+0

Pouvez-vous s'il vous plaît m'aider à comprendre l'entier 'NumTags'? Le code semble fonctionner. Merci! – Susan

+0

'NumTags' est juste une propriété de la classe' NumReviewInfo'. Lors de la création d'une nouvelle classe, vous pouvez avoir un bloc d'initialisation, dans lequel vous pouvez définir des champs/propriétés publics sur le nouvel objet. Dans ce cas, le code définit 'ReviewId' sur le nouvel objet' t.Key', et définit également la propriété 'NumReviews' sur' t.Count() '. Dans la méthode qui appelle ce code, la propriété 'NumReviews' contiendra le nombre souhaité. – dlev

+0

Une question de plus et je promets de vous laisser seul. Lorsque j'essaie d'appeler la fonction dans mon bus. Couche logique (public IEnumerable getNumReviews (RestID) - INTELLISENSE NE TROUVE PAS LE NUMReviewsInfo et le souligne ??? – Susan

2

Votre méthode est censé revenir IEnumerable<string> mais votre code renvoie une collection d'objets anonymes. De toute évidence, les deux ne sont pas les mêmes.

Il semble que vous devez créer un type de béton au lieu d'un type anonyme, puis modifier votre méthode pour retourner la collection appropriée:

public class ConcreteType 
{ 
    public string ReviewId { get; set; } 
    public int TagCount { get; set; } 
} 

Et puis changer la méthode:

public IEnumerable<ConcreteType> GetNumReviews(int restId) 
{ 
    return from REVIEW in db.REVIEWs 
      where REVIEW.REST_ID = restId 
      group REVIEW by REVIEW.REVIEW_ID into t 
      select new ConcreteType 
      { 
       ReviewId = t.Key, 
       TagCount - t.Count() 
      }; 
} 
1

Le problème est que votre collection NumReviews est tapée à IEnumerable<anonymous type> mais elle est utilisée comme le retour d'une fonction qui est tapée IEnumerable<string>. Vous devez soit

  • Modifier l'instruction select pour retourner un string
  • Modifier le type de retour et instruction select pour produire un type concret

Par exemple

struct Data { 
    internal int REVIEW_ID; 
    internal int TagCount; 
} 

public IEnumerable<Data> getNumReviews(int RestID) { 
    var NumReviews = from REVIEW in db.REVIEWs 
        where REVIEW.REST_ID == RestID 
        group REVIEW by REVIEW.REVIEW_ID into t 
        select new Data { REVIEW_ID = t.Key, TagCount = t.Count() }; 
    return NumReviews; 
} 
0

Vous aren Ne garantit pas d'obtenir une collection qui est énumérable à partir d'une requête. Vous devrez appeler .ToList() dessus pour obtenir une liste, qui est énumérable.

0

Vous êtes de retour d'un type anonyme en faisant:

select new { REVIEW_ID = t.Key, TagCount = t.Count() }; 

Qui est un type complexe. Alors que votre signature de méthode attend une collection de chaînes.

Vous pouvez:

select REVIEW_ID = t.Key 

qui correspondra à votre signature de la méthode actuelle, ou simplement changer votre signature de la méthode pour renvoyer un type complexe (peut-être un Tuple<string,int>?) Et:

public IEnumerable<Tuple<string,int>> getNumReviews(int RestID) 
{ 
    return 
    (
     from REVIEW in db.REVIEWs 
     where REVIEW.REST_ID == RestID 
     group REVIEW by REVIEW.REVIEW_ID into t 
     select new Tuple<string,int>(t.Key, t.Count()); 
    ); 
} 
Questions connexes