C# 平面数据中的层次结构,不带parentID childID

C# 平面数据中的层次结构,不带parentID childID,c#,hierarchy,C#,Hierarchy,在一个遗留数据库中,我有一个表,我试图将它打印在一个很好的层次结构html ul li列表中。我在stackoverflow上尝试了不同的答案来构建C#中的对象,但它们都有parentID和childID,在本例中这对我来说是可行的 我正在尝试这段代码,但我知道它真的很糟糕 | Level1 | Level2 | Level3 | Level4| | ELECTRONICS | TELEVISIONS | NULL

在一个遗留数据库中,我有一个表,我试图将它打印在一个很好的层次结构html ul li列表中。我在stackoverflow上尝试了不同的答案来构建C#中的对象,但它们都有parentID和childID,在本例中这对我来说是可行的

我正在尝试这段代码,但我知道它真的很糟糕

| Level1      | Level2               | Level3       | Level4|

| ELECTRONICS | TELEVISIONS          | NULL         | NULL  |

| ELECTRONICS | TELEVISIONS          | LCD          | NULL  |

| ELECTRONICS | PC                   | NULL         | NULL  |

| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS  | FLASH |

| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS   | NULL  |

| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL  |
列表层次结构(IList列表)
{
列表节点=新列表();
foreach(在列表中搜索单词x)
{
如果(x.Level2!=“”&x.Level3=“”)
{
节点=新节点();
node.Parent=x.Level1;
node.Child=x.Level2;
node.Keyword=x.Keyword;
nodes.Add(node);
//dict.Add(node.Parent,node);
}
如果(x.Level3!=“”&x.Level4=“”)
{
节点=新节点();
node.Parent=x.Level2;
node.Child=x.Level3;
node.Keyword=x.Keyword;
nodes.Add(node);
//dict.Add(node.Parent,node);
}
如果(x.Level4!=“”)
{
节点=新节点();
node.Parent=x.Level3;
node.Child=x.Level4;
node.Keyword=x.Keyword;
nodes.Add(node);
//dict.Add(node.Parent,node);
}
}
返回节点;
}

我会将此表放入一个行集合中,并对每列上的行进行分组,但这取决于最终使用的数据结构


如果您只需要HTML中的分层列表,并且它只有4列,请执行按
Level1
Level2
Level3
Level4
排序的数据库查询,然后相应地循环遍历它们。保留一个指示器,查看级别是否更改,并根据需要输出HTML代码。

为了构建真正的层次结构,您的
类节点需要在类中包含子项。将
列表
添加到
节点
以及
添加
方法中,这样数据就包含了层次结构。然后您可以构建一个HTMLLI/ul列表。例如,
节点
类可能如下所示:

    List<Node> FlatToHierarchy(IList<SearchWord> list)
    {
        List<Node> nodes = new List<Node>();

        foreach (SearchWord x in list)
        {
            if (x.Level2 != " " && x.Level3 == " ")
            {
                Node node = new Node();
                node.Parent = x.Level1;
                node.Child = x.Level2;
                node.Keyword = x.Keyword;
                nodes.Add(node);
                //dict.Add(node.Parent, node);
            }

            if (x.Level3 != " " && x.Level4 == " ")
            {
                Node node = new Node();
                node.Parent = x.Level2;
                node.Child = x.Level3;
                node.Keyword = x.Keyword;
                nodes.Add(node);
                //dict.Add(node.Parent, node);
            }

            if (x.Level4 != " ")
            {
                Node node = new Node();
                node.Parent = x.Level3;
                node.Child = x.Level4;
                node.Keyword = x.Keyword;
                nodes.Add(node);
                //dict.Add(node.Parent, node);
            }
        }

        return nodes;
    }
然后,为了构建HTMLLI/ul列表,需要递归地遍历节点结构

编辑:事实上,现在我想起来了,您可能只想从数据构建一个分层的XML文档。然后,您可以从xml构建ul/li:

public class Node
{
    public Node Parent { get; set; }
    public string ParentName { get { Parent != null ? Parent.Name : null; } }
    // ...
}
公共类数据
{
公共字符串Level1{get;set;}
公共字符串Level2{get;set;}
公共字符串Level3{get;set;}
公共字符串Level4{get;set;}
}
公共数据[]样本数据=新数据[]{
新数据{Level1=“电子”,Level2=“电视”,Level3=null,Level4=null},
新数据{Level1=“电子”,Level2=“电视”,Level3=“液晶”,Level4=null},
新数据{Level1=“ELECTRONICS”,Level2=“PC”,Level3=null,Level4=null},
新数据{Level1=“ELECTRONICS”,Level2=“便携式电子设备”,Level3=“MP3播放器”,Level4=“FLASH”},
新数据{Level1=“ELECTRONICS”,Level2=“便携式电子设备”,Level3=“CD播放器”,Level4=null},
新数据{Level1=“电子”,Level2=“便携式电子”,Level3=“双向无线电”,Level4=null},
};
XElement AddNode(字符串名称)
{
返回新的XElement(“节点”,
新的XAttribute(“名称”,名称));
}
//注意:这不是优化的,但你得到的想法。。。
XDocument BuildHierarchy(IEnumerable数据)
{
XElement根=新XElement(“根”);
XDocument xdoc=新的XDocument(根);
XElement level1=null;
XElement level2=null;
XElement level3=null;
XElement level4=null;
foreach(数据中的var项)
{
//假设item.Level1从不为空。。。
if(level1==null | | string.Compare(item.level1,level1.Attribute(“Name”).Value)!=0)
{
level1=AddNode(item.level1);
根。添加(级别1);
level2=null;
level3=null;
level4=null;
}
if(string.IsNullOrWhiteSpace(item.Level2))
{
level2=null;
level3=null;
level4=null;
继续;
}
if(level2==null | | string.Compare(item.level2,level2.Attribute(“Name”).Value)!=0)
{
level2=AddNode(item.level2);
级别1.添加(级别2);
level3=null;
level4=null;
}
if(string.IsNullOrWhiteSpace(item.Level3))
{
level2=null;
level3=null;
level4=null;
继续;
}
if(level3==null | | string.Compare(item.level3,level3.Attribute(“Name”).Value)!=0)
{
level3=AddNode(item.level3);
级别2.添加(级别3);
level4=null;
}
if(string.IsNullOrWhiteSpace(item.Level4))
{
level4=null;
继续;
}
if(level4==null | | string.Compare(item.level4,level4.Attribute(“Name”).Value)!=0)
{
level4=AddNode(item.level4);
级别3.添加(级别4);
}
}
返回xdoc;
}

为什么不从平面数据中构建继承权,然后使用它来构建html?
public class Node
{
    public Node Parent { get; set; }
    public string ParentName { get { Parent != null ? Parent.Name : null; } }
    // ...
}
public class Data
{
    public string Level1 { get; set; }
    public string Level2 { get; set; }
    public string Level3 { get; set; }
    public string Level4 { get; set; }
}

public Data[] sampleData = new Data[] {
    new Data { Level1 = "ELECTRONICS", Level2 = "TELEVISIONS", Level3 = null, Level4 = null },
    new Data { Level1 = "ELECTRONICS", Level2 = "TELEVISIONS", Level3 = "LCD", Level4 = null },
    new Data { Level1 = "ELECTRONICS", Level2 = "PC", Level3 = null, Level4 = null },
    new Data { Level1 = "ELECTRONICS", Level2 = "PORTABLE ELECTRONICS", Level3 = "MP3 PLAYERS", Level4 = "FLASH" },
    new Data { Level1 = "ELECTRONICS", Level2 = "PORTABLE ELECTRONICS", Level3 = "CD PLAYERS", Level4 = null },
    new Data { Level1 = "ELECTRONICS", Level2 = "PORTABLE ELECTRONICS", Level3 = "2 WAY RADIOS", Level4 = null },
};

XElement AddNode(string name)
{
    return new XElement("Node", 
        new XAttribute("Name", name));
}

// NOTE: This is not optimized, but you get the idea...
XDocument BuildHierarchy(IEnumerable<Data> data)
{
    XElement root = new XElement("Root");
    XDocument xdoc = new XDocument(root);
    XElement level1 = null;
    XElement level2 = null;
    XElement level3 = null;
    XElement level4 = null;

    foreach (var item in data)
    {
        // Assumes item.Level1 is never empty...
        if (level1 == null || string.Compare(item.Level1, level1.Attribute("Name").Value) != 0)
        {
            level1 = AddNode(item.Level1);
            root.Add(level1);
            level2 = null;
            level3 = null;
            level4 = null;
        }

        if (string.IsNullOrWhiteSpace(item.Level2))
        {
            level2 = null;
            level3 = null;
            level4 = null;
            continue;
        }

        if (level2 == null || string.Compare(item.Level2, level2.Attribute("Name").Value) != 0)
        {
            level2 = AddNode(item.Level2);
            level1.Add(level2);
            level3 = null;
            level4 = null;
        }

        if (string.IsNullOrWhiteSpace(item.Level3))
        {
            level2 = null;
            level3 = null;
            level4 = null;
            continue;
        }

        if (level3 == null || string.Compare(item.Level3, level3.Attribute("Name").Value) != 0)
        {
            level3 = AddNode(item.Level3);
            level2.Add(level3);
            level4 = null;
        }

        if (string.IsNullOrWhiteSpace(item.Level4))
        {
            level4 = null;
            continue;
        }

        if (level4 == null || string.Compare(item.Level4, level4.Attribute("Name").Value) != 0)
        {
            level4 = AddNode(item.Level4);
            level3.Add(level4);
        }
    }

    return xdoc;
}