我如何从数据表到asp.net c#中的层次结构

发布于 2024-10-18 16:15:44 字数 1150 浏览 4 评论 0原文

我有一个从数据库管理器类获得的数据表, 我需要将该数据转换为分层结构,

要么将其直接绑定到 .net 树视图控件,要么首先将其绑定到内存中。

我有一个 ID 列和一个 ParentID 列。 我不知道的一定是父母 ID。所以首先要做的就是找出哪个节点是父节点 ID。

循环该表并使其分层的最佳实践是什么,

BranchId     ParentId    ProductCount    HasBranchChildren       Name
0           NULL        48              1                       Categories
1           0           20              1                       CategoryA
2           1           10              1                       CategoryA1
3           1           8               0                       CategoryA2
4           1           2               0                       CategoryA3
5           2           4               0                       CategoryA1.1
6           2           6               0                       CategoryA1.2
7           0           28              1                       CategoryB
8           7           20              0                       CategoryB1
9           7           8               0                       CategoryB2

这将是一个示例数据表 当然它会有数百个项目,并且并不总是从根节点开始, 一个请求可能会请求某个类别的子集, 但是我已经与数据库团队交谈过,他们会给我根节点上的 NULL 在上面的例子中,这将是表中的元素 0 ....

I have a datatable which i get from the databasemanager class,
and i would need to transform that data into a hierarchical structure

either binding it directly to a .net treeview control or in memory first .

i have an ID column, and a ParentID column.
what i do not know necessarily is the parent ID to start with. so first thing to do would be to find out which node is the parent ID.

what would be best practice to loop over this table and make it hierarchical

BranchId     ParentId    ProductCount    HasBranchChildren       Name
0           NULL        48              1                       Categories
1           0           20              1                       CategoryA
2           1           10              1                       CategoryA1
3           1           8               0                       CategoryA2
4           1           2               0                       CategoryA3
5           2           4               0                       CategoryA1.1
6           2           6               0                       CategoryA1.2
7           0           28              1                       CategoryB
8           7           20              0                       CategoryB1
9           7           8               0                       CategoryB2

this would be an example datatable
of course it will have hundreds of items, and it does not always start at the root node,
its possible that with a request a certain subset of categories is requested,
however i've talked with the database team and they will give me NULL on root nodes
in the above example that would be element 0 in the table ....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心安伴我暖 2024-10-25 16:15:44

根节点的 ParentId 属性将/必须为 null 或 0 或某个告诉您它们没有父节点的值。然后您可以开始递归搜索以当前节点 id 作为父节点的节点。如果您只想在树中显示集合,则无需将其以分层结构保存在内存中,您可以继续构建树。像这样的事情:

// just a concept, not tested, might have errors

// ObjectWithHierarchy could look something like this
class ObjectWithHierarchy
{
    public int Id {get;set;}
    public int? ParentId {get;set;}
    public string Name {get;set;}
}

private void LoadTree()
{
    // initialize your collection of objects
    List<ObjectWithHierarchy> list = new List<ObjectWithHierarchy>();

    // build the tree
    TreeView treeView = new TreeView();

    foreach (var item in list.FindAll(i => i.ParentId == null))
    {
        // create the root node
        TreeNode rootNode = new TreeNode();
        rootNode.Text = item.Name; 
        rootNode.Tag = item;

        // load child nodes
        LoadChildNodes(node, list);

        // add the node to the treeview
        treeView.Nodes.Add(rootNode);
    }
}

private void LoadChildNodes(TreeNode node, List<ObjectWithHierarchy> list)
{
    ObjectWithHierarchy item = node.Tag as ObjectWithHierarchy;
    foreach (var childItem in list.FindAll(i => i.ParentId == item.Id))
    {
        // create the child node
        TreeNode childNode = new TreeNode();
        childNode.Text = childItem.Name;
        childNode.Tag = childItem;

        // load children, if there are any
        LoadChildNodes(childNode, list);

        // add it to its parent nodes collection
        node.Nodes.Add(childNode);
    }
}

有一些第三方控件如果知道 Id 和 ParentId 属性,那么它们“知道”如何显示层次结构。

编辑:刚刚注意到您正在使用 ASP.NET,并且代码用于 winforms 树视图,但概念大致相同。

The root node(s) will/must have the ParentId property null or 0 or some value that tells you that they don't have a parent node. Then you can start to search recursively for the nodes that have the current node id as parent. If all you want to do is display the collection in a tree, there's no need to keep it in memory in a hierarchical structure, you can just go ahead and build the tree. Something like this:

// just a concept, not tested, might have errors

// ObjectWithHierarchy could look something like this
class ObjectWithHierarchy
{
    public int Id {get;set;}
    public int? ParentId {get;set;}
    public string Name {get;set;}
}

private void LoadTree()
{
    // initialize your collection of objects
    List<ObjectWithHierarchy> list = new List<ObjectWithHierarchy>();

    // build the tree
    TreeView treeView = new TreeView();

    foreach (var item in list.FindAll(i => i.ParentId == null))
    {
        // create the root node
        TreeNode rootNode = new TreeNode();
        rootNode.Text = item.Name; 
        rootNode.Tag = item;

        // load child nodes
        LoadChildNodes(node, list);

        // add the node to the treeview
        treeView.Nodes.Add(rootNode);
    }
}

private void LoadChildNodes(TreeNode node, List<ObjectWithHierarchy> list)
{
    ObjectWithHierarchy item = node.Tag as ObjectWithHierarchy;
    foreach (var childItem in list.FindAll(i => i.ParentId == item.Id))
    {
        // create the child node
        TreeNode childNode = new TreeNode();
        childNode.Text = childItem.Name;
        childNode.Tag = childItem;

        // load children, if there are any
        LoadChildNodes(childNode, list);

        // add it to its parent nodes collection
        node.Nodes.Add(childNode);
    }
}

There are some third party controls that "know" how to display a hierarchical structure if they know the Id and ParentId properties.

EDIT: just noticed that you're using ASP.NET, and the code is for a winforms treeview, but the concept is roughly the same.

世界和平 2024-10-25 16:15:44

步骤 1.
您需要从内存中的表创建树结构,这应该很简单。在这里查看这个问题:
从邻接列表创建树的最有效方法

在这里是您的多根案例的一些代码(我不想将父值修改为某个虚假值,因此虚拟根及其直接子级将具有parent = null,但这对于遍历树并不重要,因为您有Children 和 IsRoot):

public class Branch
{
    public Branch()
    {
        Children = new List<Branch>();
    }

    public bool IsRoot { get; set; }
    public int? BranchId { get; set; }
    public int? ParentId { get; set; }
    public List<Branch> Children { get; set; }

    public int ProductCount { get; set; }       
    public int HasBranchChildren { get; set; }

    public string Name { get; set; }
    //other data
}

public class BranchTreeHelper
{
    public Branch MakeTree() 
    {
        var virtualRoot = new Branch()
        {
            BranchId = null,
            ParentId = null,
            IsRoot = true
        };

        // get the data from db, just disregard the properties: Children and IsRoot flage
        List<Branch> branchList = GetDataFromDB();

        var branchDict = branchList.ToDictionary(i => i.BranchId.Value, i => i);

        foreach(var branch in branchList)
        {
            if(branch.ParentId.HasValue)
            {
                branchDict[branch.ParentId.Value].Children.Add(branch);
            }
            else
            {
                virtualRoot.Children.Add(branch);
            }
        }

        return virtualRoot;
    }
}

步骤 2。
遗憾的是,微软没有提供一种简单的通用方法来绑定分层数据,这让事情变得很困难。但幸运的是,其他人已经创建了可以做到这一点的代码。使用它将新的树结构绑定到树视图:
http://ohds.codeplex.com/

从项目主页:

ObjectHierarchicalDataSource 是
分层数据源是什么
ObjectDataSource 是表格数据
来源。它使页面开发人员
以声明方式绑定层次结构
Menu 和 TreeView 等控件
几乎任何对象图。

您可以创建自己的自定义实现 IHierarchicalDataSource< /a> 但我强烈建议不要这样做,因为这很麻烦而且容易出错。

选项 2:
如果您不想使用第三方用户控件,请签出此IHierarchicalDataSource 的通用实现,它可以再次绑定到任何分层 ASP.NET 控件:
http://elegantcode.com/2008/04/06/aspnet-hierarchicaldatasourcet/< /a>

Step 1.
You need to create a tree structure from a table in memory from, this should be simple. Checkout this question here:
Most efficient way of creating tree from adjacency list

Here is some code for your multi root case (I did not want to modify the parent values to some bogus value, therefore the virtual root and its immediate children will have parent = null, but that doe not matter for traversing the tree, since you have Children and IsRoot):

public class Branch
{
    public Branch()
    {
        Children = new List<Branch>();
    }

    public bool IsRoot { get; set; }
    public int? BranchId { get; set; }
    public int? ParentId { get; set; }
    public List<Branch> Children { get; set; }

    public int ProductCount { get; set; }       
    public int HasBranchChildren { get; set; }

    public string Name { get; set; }
    //other data
}

public class BranchTreeHelper
{
    public Branch MakeTree() 
    {
        var virtualRoot = new Branch()
        {
            BranchId = null,
            ParentId = null,
            IsRoot = true
        };

        // get the data from db, just disregard the properties: Children and IsRoot flage
        List<Branch> branchList = GetDataFromDB();

        var branchDict = branchList.ToDictionary(i => i.BranchId.Value, i => i);

        foreach(var branch in branchList)
        {
            if(branch.ParentId.HasValue)
            {
                branchDict[branch.ParentId.Value].Children.Add(branch);
            }
            else
            {
                virtualRoot.Children.Add(branch);
            }
        }

        return virtualRoot;
    }
}

Step 2.
Sadly MS made it difficult, by not offering a simple generic way to bind to hierarchical data. But luckily others have created code that can. Use this to bind your new tree structure to a tree view:
http://ohds.codeplex.com/

From the project homepage:

ObjectHierarchicalDataSource is to
hierarchical data sources what
ObjectDataSource is to tabular data
sources. It enables the page developer
to declaratively bind hierarchical
controls such as Menu and TreeView to
almost any object graph.

You could create you're own custom implementation of IHierarchicalDataSource but I would strongly advise against that since this is cumbersome and error prone.

Option 2:
If you do not want to use third party user controls the checkout this generic implementation of IHierarchicalDataSource this again can be bound to any hierarchical ASP.NET control:
http://elegantcode.com/2008/04/06/aspnet-hierarchicaldatasourcet/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文