Преобразовать наборы данных в общий список - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть свойства класса, как показано ниже

public class Country
{
   CountryId,
   CountryName,
   List<State>
}

Public class State
{
   StateId,
   StateName,
   List<City>
}

Public class City
{
   CityId,
   CityName
}

У меня есть набор данных для каждого класса, который извлекает данные из БД, как показано ниже.

CountryDS  
`````````  
CountryId | CountryName
1         | India  
2         | China  

StateDS  
```````  
CountryId | StateId | StateName  
1         | 1       | UP  
1         | 2       | MP  
1         | 3       | Punjab  
2         | 10      | Beijing  

CityDS  
``````  
StateId | CityId | CityName  
1       | 1      | Agra  
1       | 2      | Mathura  
2       | 5      | Ujjain  
2       | 7      | Dewas  
3       | 10     | Amritsar  

Теперь я хочу преобразовать этинаборы данных для List<Country> объекта, без вложенных циклов или с LinQ или лучшим способом быстрого извлечения данных.

Country  
--> CountryId  
    CountryName  
    State  
    --> StateId  
        StateName  
        City  
        --> CityId  
            CityName  

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

... но создание объекта занимает много времени, так как у меня есть записи в миллионах, так как в одной стране может быть много штатов, а в одном штате много городов.Так что я хочу, если есть способ сделать это с Linq.

Имейте в виду, LINQ оптимизирован для повторного использования, а не для быстрого кода.Внутренне LINQ будет использовать foreach, что вызовет GetEnumerator() и MoveNext().foreach, который разработан специально для вашего решения, вероятно, будет быстрее, чем LINQ foreach, и вы можете оптимизировать еще больше, вызывая перечисление себя (GetEnumerator и MoveNext).

Тем не менее, есливы хотите использовать LINQ всякий раз, когда вам нужны объекты со своими подобъектами (обычно с внешним ключом), например, школы со своими учениками, библиотеки со своими книгами, страны со своими государствами, Enumerable.Groupjoin - этопуть.

Таким образом, у вас есть три коллекции, использующие первичные ключи и иностранные ключи для указания друг на друга:

IEnumerable<Country> countries = ...
IEnumerable<State> states = ...
IEnumerable<City> cities = ...

И вы хотите, чтобы коллекция стран с их государствами, где каждыйШтат имеет свои города.

var result = countries.GroupJoin(states,  // GroupJoin countries and states
   country => country.Id,                 // from the country take the primary key
   state => state.CountryId               // from the state take the foreign key
   (country, statesOfCountry) => new      // from every country with all its states
   {                                      // make one new object
       Id = country.Id,                   // cointaining only the properties you plan to use
       Name = country.Name,
       ...

       States = ...                       // see below
   }

Чтобы вычислить States of every country with their cities, мы Groupjoin statesOfCountry коллекция с коллекцией cities, при сопоставлении первичного и внешнего ключа:

Продолжая LINQ выше:

States = statesOfCountry.GroupJoin(cities,   // Groupjoin states with cities
   stateOfCountry => stateOfCountry.Id,      // from every state take the Id
   city => city.StateId,                     // from every city take the stateId
   (stateOfCountry, citiesOfState) => new    // again: when they match make a new object
   {
        // for performance: select only the properties yo actually plan to use
        Id = stateOfCountry.Id,
        Name = stateOfCountry.Name,

        // not needed: you know it equals Country.Id:
        // CountryId = stateOfCountry.CountryId,

        Cities = citiesOfState.Select(city => new
        {
             // only the properties you plan to use
             Id = city.Id,
             Name = city.Name,
             Location = city.Location,

             // not needed, you already know the value:
             // StateId = city.StateId,
        }),
   }

Приятно то, что вы создали только перечислимый объект, а именно: вы создали только то, что умеет перечислять.Вы еще не перечислили.Преимущество в том, что это очень быстро, и если во время перечисления вы решите, что вам не нужна какая-то информация, вам не нужно будет ее перечислять.

Например, как только вы начнете перечисление и захотитеигнорировать все города русских городов:

foreach (var country in result)
{
     if (country.Name != "Russia")
        ProcessCountry(country);
     // else: ignore

Преимущество этого состоит в том, что групповое соединение российских городов не будет выполнено

0 голосов
/ 27 ноября 2018

Без использования LinQ или вложенных циклов вы можете добиться этого с помощью небольшого обходного пути.

  1. Преобразование вашего DataSet в JSON.
  2. Анализ JSON для соответствующих объектов.

Вы можете использовать newtonsoft для сериализации или десериализации.

...