Структура иерархических категорий C #

Я разрабатываю небольшое приложение для Windows на C # и нуждаюсь в дизайне структуры иерархических категорий. В настоящее время я использую однослойные категории из БД, то есть без дочерних категорий. Я хотел бы позволить пользователю создавать многоуровневые категории. Я заглянул в эту ветку Структура данных для категории, но подумал, есть ли более простой способ справиться с такого рода проблемами? потому что я не уверен, что это лучшее решение проблемы.

Я был бы признателен, если бы кто-нибудь мог предоставить структуру таблицы БД и некоторый код кода C #, связанный с ней. Также я хотел проверить, могу ли я получить все идентификаторы дочерней категории (включая дочерние) от ее родителя.


person Harvinder    schedule 16.12.2009    source источник


Ответы (5)


create table Category
(
     id int primary key identity,
     parent_id int,
     name varchar(100),
     foreign key (parent_id) references Category (id)
)

public class Category
{
    private int id; 
    private string name;
    private Category Parent;
    private IList<Category> Children;
}

Это наивное решение для создания дерева, и когда вы повторно гидрируете иерархию объектов, это решение потребует нескольких выборок из БД. Вам также необходимо сохранить некоторую информацию, которая уменьшит количество выборок, и запомнить порядок узлов в дереве.

У Джо Селко есть Другие деревья и иерархии в SQL "на sqlteam.com

person expedient    schedule 16.12.2009

Если ваша иерархия жесткая и не изменится, вы можете жестко ее запрограммировать.

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

person Oded    schedule 16.12.2009

Харвиндер,

Вы рассматривали возможность использования элемента управления TreeView для своих целей? Думаю, это была бы прекрасная идея. Пожалуйста, посетите сайт MSDN, чтобы узнать об элементе управления TreeView. Щелкните здесь.

person Piotr Justyna    schedule 16.12.2009
comment
Привет, да, древовидное представление действительно отвечает некоторым моим требованиям, но я хотел бы иметь реальные изображения для каждой записи (строки) в списке. Я нашел библиотеку ObjectListView и, кажется, могу с этим справиться. objectlistview.sourceforge.net/cs/index.html - person Harvinder; 19.12.2009

Харвиндер,

Структура базы данных, о которой вы думаете, будет работать идеально, но у нее есть несколько недостатков:

  • простой запрос sql, обнаруживающий все дочерние элементы указанного узла, невозможен (вам придется выполнять строковые операции)
  • сортировка по количеству детей невозможна из запроса sql
  • чтобы получить коллекцию дочерних узлов узла, вам придется подключаться к базе данных несколько раз (чтобы получить каждый дочерний элемент отдельно по его идентификатору)
  • и Т. Д.

Наиболее распространенная практика - хранить один идентификатор (родительский) в одном столбце. В этом случае несколько дочерних элементов могут указывать на одного и того же родителя (отношение «один ко многим»), что эффективно решает вашу проблему.

На вторую часть вашего вопроса можно легко ответить: если вам действительно не нужно, не используйте Windows Forms (оба автора использовали его) - вы очень утомитесь, привязывая свою структуру данных к вашему представлению. Гораздо лучше использовать WPF для ваших целей и гибко изменять шаблоны данных Combobox и Treeview в соответствии с вашими требованиями. Если вы не знакомы с WPF, начните с просмотра этого блестящая статья о шаблонах проектирования WPF и MVVM - она ​​даже содержит примеры Treeview, которые будут полезны в вашем случае.

Скажите, пожалуйста, решил ли мой ответ вашу проблему. Буду рад ответить на любые ваши вопросы по WPF.

person Piotr Justyna    schedule 21.12.2009
comment
Спасибо за подробности, да, сохранение parent_id кажется гораздо лучшим решением проблемы. Однако вместо этого я буду использовать children_id, потому что мои требования заключаются в том, что я могу получить всех дочерних элементов, как только у меня будет родитель, который я буду обрабатывать из своего приложения, а не из базы данных (я знаю, что это будет очень дорогостоящий цикл ЦП) но мне кажется более простым решением. Итак, я возьму все категории, динамически загружаемые в приложение, и создам оттуда дерево, это будет всего лишь небольшой рекурсивный метод. - person Harvinder; 22.12.2009
comment
Теперь я нахожусь на пути к хорошей библиотеке для работы с изображениями в treelistviews, я нашел хорошую библиотеку под названием ObjectListView, и она обрабатывает изображения, но документации и примеров не так много, поэтому все еще тестирую и играю с ней. . Спасибо - person Harvinder; 22.12.2009
comment
Не проблема :) Есть вопросы - задавайте мне. - person Piotr Justyna; 22.12.2009

Спасибо за ответы и внимание к моему вопросу.

В настоящее время у меня уже есть структура для настроек одной категории, я знаю довольно легко. Я думал о том, чтобы выбрать более простой маршрут (я думаю, что это более простой маршрут, но, возможно, ошибаюсь).

В настоящее время я подумываю добавить дополнительный столбец в таблицу категорий под названием children_ids. Чтобы все родители вели учет своих детей, а не наоборот. Столбец children_ids может иметь текстовый тип, а идентификаторы могут храниться в строковом формате, т.е. 1-4-5-7-8 и т. Д., И как только я получу этот столбец из БД, я могу разделить строку с помощью '-' и получить все идентификаторы для своих детей.

Думаю, так мне будет немного легче следить за всем населением;), просто спроси родителей об их детях. Я думаю, что это также упростит поиск зависимостей, потому что мне нужно будет только быстрее получить список всех дочерних элементов (все уровни ниже рекурсивно). Таким образом, я также могу отсортировать все записи перед загрузкой их из БД, еще одна головная боль исчезла.

Я уверен, что должны быть лучшие решения, но не знаю, будет ли это проще или нет.

Другим моим требованием было создать раскрывающееся поле со списком со стилем «дочерний-родительский» для этой категории, аналогичным структуре списка папок, которую пользователи могли бы выбирать через них. Может быть, что-то вроде пример CodeProject или пример CodeGuru, я мог бы использовать любой из подходов, чтобы немного облегчить себе жизнь.

Проблема в том, что я хотел бы добавить больше деталей в каждую запись раскрывающегося меню, например, cat_id и т.д., но не хочу, чтобы они были видны пользователю, это необходимо для получения подробностей о выборе пользователя. Я предполагаю, что мне придется компенсировать это, имея отдельный ArrayList, возможно, со всеми деталями категорий, а затем просто перейти к его местоположению индекса, как только пользователь выберет запись из раскрывающегося списка. Я правильно думаю?

Спасибо за чтение и за ответы!

person Harvinder    schedule 18.12.2009