Tree structures in ASP.NET and SQL Server

Displaying Breadcrumbs

One common theme when dealing with trees (especially in a web context) is to be able to provide what is known as a "breadcrumb" - that is, the path from the root of the tree, to the one we're looking at. For instance, on Developer Fusion the breadcrumb when you look at the ASP.NET section is Web Directory / Programming Languages / ASP.NET.

In order to do this, we need to fetch all rows whose lineage column is a prefix of the lineage column for the node we want to navigate to in the tree. For instance, if we're looking at a node childC whose lineage column is /root/childA/childC/, then we want to return the nodes with lineage columns /root/childA/ and /root/ - that is, the two nodes root and childA.

We'll use the LIKE operator again here, but this could equally be done using a combination of the LEFT and LEN functions.

CREATE PROCEDURE dfTreeGetPath ( @id INT ) AS

SELECT * FROM dfTree WHERE
    (SELECT lineage FROM dfTree WHERE id = @id) LIKE lineage + '%'
ORDER BY lineage, name

Although we've represented the tree in the SQL Server database, when we execute the dfTreeGetPath stored procedure, we still get a totally linear set of data back. For the moment though, we're not going to bother trying to re-create the tree structure by populating the TreeNode's Children collection. For one thing, it's a little complicated (and explained later), and secondly - we've got no need to. By sorting on the lineage and name columns, the rows are actually going to come back in a very sensible order - the root node first, and the node we're looking at last. To create our breadcrumb on a web page, we'll actually just end up binding an ASP.NET repeater control to this list of nodes.

Here's the code for our SqlServerTreeProvider class.

public ArrayList GetPath(int uniqueID)
{
    return ProcessList("dfTreeGetPath",
        new SqlParameter("@id",uniqueID));
}

In order to add our breadcrumb to the page we defined earlier, we add a new repeater to the page.

<asp:Repeater Runat="server" ID="breadcrumb">
    <ItemTemplate>
        <a href='<%# "TreeDemo.aspx?id=" + DataBinder.Eval(Container.DataItem,"UniqueID") %>'>
            <%# DataBinder.Eval(Container.DataItem,"Name") %></a>
    </ItemTemplate>
    <SeparatorTemplate> / </SeparatorTemplate>
</asp:Repeater>

And then simply add the following code to our Page_Load event.

breadcrumb.DataSource = treeProvider.GetPath(treeID);
breadcrumb.DataBind();

You'll also need to have populated the database with some dummy information by this point! After having clicked "Create Nodes" in your browser, you should see something like this:

A diagram displaying the structure of the table, with these fields: id (int, primary key), parentId (int), name (varchar), depth (int), lineage (varchar).

Looking a bit more hopeful now, isn't it? Because of the way we've designed the database, we've got no limit on the depth of the tree or the number of children that can be displayed. We can also store more than one tree in the database - by simply adding a new root node.

You might also like...

Comments

About the author

James Crowley

James Crowley United Kingdom

James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audien...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“We better hurry up and start coding, there are going to be a lot of bugs to fix.”