В C #, как я должен создать csv из родительско-дочерней таблицы?

#c#

#c#

Вопрос:

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

 ID, ParentID, Name, Population
1, Null, Asia, 40
2, Null, Africa, 20
3, 1, China, 10
4, 3, Tibet, 5
  

(около 1000 строк и уровни дерева могут различаться. Пользователь будет продолжать вводить новые строки)

Я хочу получить csv-файл, который выглядит следующим образом:

 Level1, Level2, Level3, Population
Asia, Null, Null, 40
Africa, Null, Null, 20
Asia, China, Null, 10
Asia, China, Tibet, 5
  

Как мне создать такой csv-файл из родительско-дочерней таблицы? Первая задача — найти максимальное количество уровней родительско-дочерней таблицы, а затем создать заголовки csv. Вторая задача состоит в том, чтобы затем поместить null для уровней, которые не имеют значения.

Пожалуйста, обратите внимание, что пользователи будут продолжать вводить новые строки… не уверен, должен ли я загружать родительско-дочернюю таблицу в формате xml, а затем начинать чтение XML-файла… пожалуйста, предложите какой-нибудь способ. Спасибо

Комментарии:

1. вы сохраняете таблицы на сервере MS-SQL?

2. И ваша таблица хранится в реляционной базе данных? Почти даю вам -1 за то, что вы не упомянули ни слова о том, как / где хранятся эти данные.

3. То, что вы хотите сделать, не является разумной практикой базы данных.

4. он хранится в базе данных MS SQL.

Ответ №1:

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

При построении вашего дерева вы, вероятно, захотите отметить максимальную глубину конечного узла. Это даст вам количество элементов в строке заголовка в вашем csv. Затем во время обхода вы захотите отслеживать путь узлов от вашего корня, это будет то, что вы печатаете в своем csv, количество узлов в этом пути можно вычесть из вашей максимальной глубины, чтобы получить количество нулей в данной строке.

Ваш класс узла будет выглядеть примерно так:

 class Node
{
    string name;
    int population;

    Node parent;
    List<Node> children;

    public Node(Node parent, string name, int population)
    {
        this.parent = parent;
        this.name = name;
        this.population = population;
        children = new List<Node>();
    }


    public void Add(Node child)
    {
        children.Add(child);
    }
}
  

Комментарии:

1. если я сериализую его в xml, не будет ли он жаловаться на циклическую ссылку

2. Я не понимаю, почему вы не можете сделать это в памяти.

3. пока все хорошо. я опубликую свой полный ответ позже. как мне найти максимальное количество уровней после создания списка <Node> с родительскими, дочерними элементами в качестве общедоступных свойств. какая-то логика проверки родительского значения равна нулю? должен ли я проанализировать все узлы и т.д.? есть ли умный способ использовать лямбда-выражения?

4. я перебирал каждый элемент и рекурсивно получал parent, пока parent не стал null и не выбрал максимальный уровень дерева

5. @KnowledgeSeeker Если вы не отслеживаете это при построении своего дерева, вам, по сути, придется пройти через него, чтобы узнать.

Ответ №2:

 create table #Populations (ID int PRIMARY KEY, ParentId int null, Name varchar(20), Population int )
insert into #Populations values(1, null, 'Asia', 40)
insert into #Populations values(2, Null, 'Africa', 20)
insert into #Populations values(3, 1, 'China', 20)
insert into #Populations values(4, 3, 'Tibet', 10)

;with FirstLevel(ID, ParentId, Name, Population, Breadcrumb, Level, LevelStr) AS
(
    select ID, ParentId, Name, Population
        , convert(varchar(max),Name) as [Breadcrumb]
        , Level = 1
        , convert(varchar(max),'Level1')
    from #Populations
    where ParentId is null
    union all 
    select p.ID, p.ParentId, p.Name, p.Population
        ,convert(varchar(max),[Breadcrumb]   ', '   p.Name)
        ,Level   1, convert(varchar(max)
        ,LevelStr   ', Level'   convert(varchar(2), Level   1))
    From #Populations p
    inner join FirstLevel on FirstLevel.ID = p.ParentId
)
select top 1 LevelStr   ', Population' as CsvRow
from FirstLevel
where Level = (select max(level) from FirstLevel)
union all
select Breadcrumb   ','   coalesce(replicate(',',(select max(level) from FirstLevel) - Level - 1), '')   ' '   convert(varchar(20), Population)
from FirstLevel

drop table #Populations