web-dev-qa-db-fra.com

Comment aplatir des objets imbriqués avec une expression linq

J'essaie d'aplatir les objets imbriqués comme ceci:

public class Book
{
    public string Name { get; set; }
    public IList<Chapter> Chapters { get; set; }
}

public class Chapter
{
    public string Name { get; set; }
    public IList<Page> Pages { get; set; }
}


public class Page
{
    public string Name { get; set; }
}

Laissez-moi faire un exemple. Ce sont les données que j'ai

Book: Pro Linq 
{ 
   Chapter 1: Hello Linq 
   {
      Page 1, 
      Page 2, 
      Page 3
   },
   Chapter 2: C# Language enhancements
   {
      Page 4
   },
}

Le résultat que je recherche est la liste à plat suivante:

"Pro Linq", "Hello Linq", "Page 1"
"Pro Linq", "Hello Linq", "Page 2"
"Pro Linq", "Hello Linq", "Page 3"
"Pro Linq", "C# Language enhancements", "Page 4"

Comment pourrais-je accomplir ceci? Je pourrais le faire avec un select new mais on m'a dit qu'un SelectMany serait suffisant.

109
abx78
myBooks.SelectMany(b => b.Chapters
    .SelectMany(c => c.Pages
        .Select(p => b.Name + ", " + c.Name + ", " + p.Name)));
176
Yuriy Faktorovich

En supposant que books soit une liste de livre:

var r = from b in books
    from c in b.Chapters
    from p in c.Pages
    select new {BookName = b.Name, ChapterName = c.Name, PageName = p.Name};
48
boca
myBooks.SelectMany(b => b.Chapters
    .SelectMany(c => c.Pages
        .Select(p => new 
                {
                    BookName = b.Name ,
                    ChapterName = c.Name , 
                    PageName = p.Name
                });
2
Madhukar Bhandari

J'essayais de faire cela aussi, et d'après les commentaires de Yuriy et sa façon de jouer avec linqPad, j'ai ceci ..

Notez que je n'ai ni livres, ni chapitres, ni pages, ni personne (livres), companyPerson (chapitres) et sociétés (pages)

from person in Person
                           join companyPerson in CompanyPerson on person.Id equals companyPerson.PersonId into companyPersonGroups
                           from companyPerson in companyPersonGroups.DefaultIfEmpty()
                           select new
                           {
                               ContactPerson = person,
                               ContactCompany = companyPerson.Company
                           };

ou

Person
   .GroupJoin (
      CompanyPerson, 
      person => person.Id, 
      companyPerson => companyPerson.PersonId, 
      (person, companyPersonGroups) => 
         new  
         {
            person = person, 
            companyPersonGroups = companyPersonGroups
         }
   )
   .SelectMany (
      temp0 => temp0.companyPersonGroups.DefaultIfEmpty (), 
      (temp0, companyPerson) => 
         new  
         {
            ContactPerson = temp0.person, 
            ContactCompany = companyPerson.Company
         }
   )

Site de référence que j'ai utilisé: http://odetocode.com/blogs/scott/archive/2008/03/25/inner-outer-lets-all-join-together-with-linq.aspx

0
Mastro