2009-07-07 5 views
3

J'ai une structure qui ressemble à peu près comme ceci:LINQ et le groupe par des données imbriquées dans une structure

List<ProductLine> -> ID 
        Name 
        ... 
        List<LineOfBusiness> -> ID 
              Name 
              ... 
              List<Watchlist> -> ID 
                   Name 
                   ReportCount 

une liste de surveillance peut exister sous plusieurs LOB mais le ReportCount ne sera pour le compte des rapports qui existent sous ce LoB pour cette WatchList. J'ai besoin d'eux dans la structure de cette façon parce que le nombre de rapports existant dans une LoB pour une Watchlist donnée est important ailleurs. Ce que je dois faire est d'obtenir une liste des différentes WatchLists (groupées en fonction de l'ID) et que le ReportCount soit la SUM du ReportCount de cette liste de surveillance dans toutes les LoB. Je n'arrive pas à faire fonctionner correctement la logique de sélection imbriquée.

Répondre

8

La technique pour aplatir une structure hiérarchique consiste à utiliser la méthode SelectMany. Vous avez besoin de quelque chose comme ceci:

var result = mainList.SelectMany(x => x.LineOfBusinessList) 
        .SelectMany(lob => lob.Watchlists) 
        .GroupBy(wl => wl.ID) 
        .Select(g => new { 
          WatchlistID = g.Key, 
          WatchlistName = g.First().Name, 
          ReportCount = g.Sum(item => item.ReportCount) 
        }); 

Le premier appel SelectMany transformera la liste initiale à la séquence de tous les objets LineOfBusiness dans tous les articles. Le second appel SelectMany va transformer une séquence d'objets LineOfBusiness en une séquence contenant tous les objets Watchlist eux. Ensuite, vous regroupez ces Watchlist s par ID et effectuez la requête réelle sur eux.

+0

le g.Key.ID ne fonctionne pas, ni le g.Key.Name. Je suppose que je peux sélectionner le WatchlistID en demandant g.Key, mais comment puis-je obtenir le nom? – Parrots

+0

Perroquets: Oups. Oui tu as raison. À l'origine, je pensais que Watchlist possédait son propre identifiant unique et que vous cochez Equals ... En fait, vous ne regroupez pas par nom, donc la requête pense que les noms peuvent être différents. Puisque vous savez que le nom est unique, utilisez simplement g.First(). Name pour l'obtenir. –

+0

@Parrots: Btw, voir la mise à jour de la réponse. –

Questions connexes