LINQ: группировка подгруппы

Как сгруппировать Подгруппу, чтобы создать список Континентов, где у каждого Континента есть свои округа, и у каждой страны есть свои города как эта таблица

введите описание изображения здесь

Вот т-sql:

select Continent.ContinentName, Country.CountryName, City.CityName 
from  Continent
left join Country
on Continent.ContinentId = Country.ContinentId

left join City
on Country.CountryId = City.CountryId

и результат t-sql:

введите описание изображения здесь

Я пробовал это, но это неправильно группирует данные, мне нужно сгруппировать в точности как в таблице выше

  var Result = MyRepository.GetList<GetAllCountriesAndCities>("EXEC sp_GetAllCountriesAndCities");

    List<Continent> List = new List<Continent>();


    var GroupedCountries = (from con in Result
                             group new
                             {


                                 con.CityName,

                             }

                             by new
                             {

                                 con.ContinentName,
                                 con.CountryName
                             }

            ).ToList();

    List<Continent> List = GroupedCountries.Select(c => new Continent()
    {

        ContinentName = c.Key.ContinentName,
        Countries = c.Select(w => new Country()
        {
            CountryName = c.Key.CountryName,

            Cities = c.Select(ww => new City()
            {
                CityName = ww.CityName
            }
            ).ToList()

        }).ToList()


    }).ToList();

2 ответа

Решение

Вам нужно сгруппировать все по континентам, по странам и странам по городам:

List<Continent> List = MyRepository.GetList<GetAllCountriesAndCities>("EXEC sp_GetAllCountriesAndCities")
    .GroupBy(x => x.ContinentName)
    .Select(g => new Continent 
    {
        ContinentName = g.Key,
        Countries = g.GroupBy(x => x.CountryName)
                     .Select(cg => new Country 
                     {
                         CountryName = cg.Key,
                         Cities = cg.GroupBy(x => x.CityName)
                                    .Select(cityG => new City { CityName = cityG.Key })
                                    .ToList()
                     })
                     .ToList()
    })
    .ToList();

Вы должны применить группировку дважды

var grouped = Result
    .GroupBy(x => x.CountryName)
    .GroupBy(x => x.First().ContinentName);

var final = grouped.Select(g1 => new Continent
{
    ContinentName = g1.Key,
    Countries = g1.Select(g2 => new Country
    {
        CountryName = g2.Key,
        Cities = g2.Select(x => new City { CityName = x.CityName }).ToList()
    }).ToList()
});

Я знаю, что это старый, но я хотел бы упомянуть гораздо более простой способ для microsoft, который немного более читабелен. Это пример только с двумя уровнями, но он, скорее всего, будет работать для других, которые достигают этой страницы (например, меня).

 var queryNestedGroups =
        from con in continents
        group con by con.ContinentName into newGroup1
        from newGroup2 in
            (from con in newGroup1
             group con by con.CountryName)
        group newGroup2 by newGroup1.Key;

Документация для этого находится на https://docs.microsoft.com/en-us/dotnet/csharp/linq/create-a-nested-group и в качестве примера используется объект Student.

Я хочу упомянуть, что метод, который они используют для печати, сложнее, чем просто создание функции быстрой печати на вашем объекте континента.

Другие вопросы по тегам