Вложенный foreach для подпунктов в C# - PullRequest
0 голосов
/ 14 января 2020

Я хочу добавить данные из базы данных как элемент и подпункт в словарь. Когда у меня есть словарь, отсортированный по элементам и подпунктам, я смогу добавить этот словарь в поле со списком, как я буду sh. У меня есть структура базы данных, подобная этой:

id      item            slug            parent_id
--------------------------------------------------
1       Audi            audi            0
2       BMW             bmw             0
3       Ferrari         ferrari         0
4       A3              a3              1
5       A4              a4              1
6       A5              a5              1
7       A6              a6              1
8       Mercedes-Benz   mercedes-benz   0
9       CLA             cla             8
10      CLS             cls             8
11      C Series        c-series        8
12      S Series        s-series        8
13      SLS AMG         sls-amg         8
14      Mitsubishi      mitsubishi      0
15      Porsche         porsche         0
16      Skoda           skoda           0
17      Tesla           tesla           0
18      A7              a7              1
19      Q3              q3              1
20      SL              sl              8
21      300             300             8
22      Toyota          toyota          0
23      Volkswagen      volkswagen      0
24      A8              a8              1
25      Q2              q2              1
26      Volvo           volvo           0
27      Q5              q5              1
28      Q7              q7              1
29      RS              rs              1
30      80 Series       80-series       1

В этой структуре базы данных я хочу получить данные для словаря, в котором подэлементы будут расположены под их родительским элементом с помощью teqel. Это простая схема:

Audi
    - 80 Series
    - A3
    - A4
    - A5
    - A6
    - A7
    - A8
    - Q2
    - Q3
    - Q5
    - Q7
    - RS
BMW
Ferrari
Mercedes-Benz
    - 300
    - CLA
    - CLS
    - C Series
    - S Series
    - SL
    - SLS AMG
Mitsubishi
Porsche
Skoda
Tesla
Toyota
Volkswagen
Volvo

Для этого sh я закодировал это так:

var listed_items = new Dictionary<int, string> { { 0, "--- Select item ---" } };
foreach (var it in _db.Items.Where(x => x.parent_id == 0))
{
    listed_items.Add(Convert.ToInt32(it.id), it.item);

    foreach (var sub_it in _db.Items.Where(x => x.parent_id > 0))
    {
        if (it.id == sub_id.parent_id)
        {
            listed_items.Add(Convert.ToInt32(sub_id.id), "   - " + sub_it.item);
        }
    }
}

Но подэлементы не расположены под родительскими элементами.

1 Ответ

5 голосов
/ 14 января 2020

Если вы хотите сгруппировать их по родительскому идентификатору, то

var dictionary = _db.Items
                    .GroupBy(x => x.parent_id)
                    .ToDictionary(x => x.Key, y => y.ToList());

поместит все элементы в Dictionary<int, List<dbItemTypeName>>, где ключом является parentID, а список содержит все элементы с этим parentID.

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

var dictionary = _db.Items
                    .OrderBy(x => x.parent_id == 0 ? x.id : x.parent_id)
                    .ThenBy(x => x.parent_id)
                    .ToDictionary(x => x.id, y => y);
var sortedDictionary = new SortedDictionary<int,DBItemType>(dictionary);

, где DBItemType - это тип элементов, содержащихся в _db. Если вам интересно, что здесь происходит - мы сначала упорядочиваем по результату x.parent_id == 0 ? x.id : x.parent_id, потому что он сгруппирует родительские элементы с потомками (мы используем обычный id, если parent_id равен 0), затем упорядочиваем по parent_id чтобы получить родительский элемент наверх (это parent_id равно 0).

Если вы хотите выбрать строковое представление элементов вместо самих элементов:

var dictionary = _db.Items
                    .OrderBy(x => x.parent_id == 0 ? x.id : x.parent_id)
                    .ThenBy(x => x.parent_id)
                    .ToDictionary(x => x.id, y => y.parent_id == 0 ? y.item : $"   -{y.item}");
var sortedDictionary = new SortedDictionary<int,string>(dictionary);

Затем обязательно установите для свойства DisplayMember ComboBox значение "Value" и свойство ValueMember до "Key"

...