Search code examples
c#asp.netsql-serverwebformsbreadcrumbs

Site Navigation / Breadcrumb using ASP.Net Web form and C#


I am working on a website which have pages arranged in one table with Parent Child Relation. Page depth can go to any level and i want to generate BreadCrumb for the website based on the database. Sample Data and data fields as shown in the Image below.

Basic Table Structure is like TableName Web_Pages

Table Columns ( PageID int, PageName Varchar, PageInternalLinkURL Varchar,PageInheritance int)

Example of Sample Data in the table Example of Table Data

Example of BreadCrumb on Page Example of BreadCrumb on Page

I want the Bread crumb for the site navigation to look similar to what is shown in the sample image below.

I tried for weeks but was not able to get it right.

I want to use it with out site map, rather i would like to create it grammatically and link the PageName field with the correct Page URL.

I want to do it so that when ever a page is added to CMS Bread crumb is created dynamically which can work with any page depth.

I worked with CTE query which is not working properly. I would appreciate if someone resolve this issue or can point to a complete working example which is similar to mine.

Testing CTE not working

SELECT * FROM pg_Pages;
WITH RecursiveTable (PageId, PageInheritance, Level)
AS
(
   --Anchor
    SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
    FROM pg_Pages AS tt
    WHERE PageInheritance = 0
    UNION ALL
    --Recursive member definition
    SELECT  tt.PageId, tt.PageInheritance, LEVEL + 1
    FROM pg_Pages AS PageId
        INNER JOIN RecursiveTable rt ON
        tt.PageInheritance = rt.PageId
)
SELECT * 
FROM RecursiveTable

Solution

  • It looks like your CTE is wrong - you are almost there but the Recursive Member Definition bit looks wrong.

    Try:

    SELECT * FROM pg_Pages;
    WITH RecursiveTable (PageId, PageInheritance, Level)
    AS
    (
       --Anchor
        SELECT      tt.PageId,  tt.PageInheritance,  0 AS Level
        FROM pg_Pages AS tt
        WHERE PageInheritance = 0
        UNION ALL
        --Recursive member definition
        SELECT  tt.PageId, tt.PageInheritance, Level + 1
        FROM pg_Pages AS tt
            INNER JOIN RecursiveTable rt ON
            tt.PageInheritance = rt.PageId
    )
    SELECT * 
    FROM RecursiveTable
    --SELECT * FROM RecursiveTable WHERE Level = 0
    

    In your original attempt, your alias for pg_Pages needs to be tt (and you need to prefix PageInheritance with tt too).

    Otherwise, it looks fine.

    EDIT

    For your additional question, you can just add the additional columns:

    SELECT * FROM pg_Pages;
    WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
    AS
    (
       --Anchor
        SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
        FROM pg_Pages AS tt
        WHERE PageInheritance = 0
        UNION ALL
        --Recursive member definition
        SELECT  tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
        FROM pg_Pages AS tt
            INNER JOIN RecursiveTable rt ON
            tt.PageInheritance = rt.PageId
    )
    SELECT * 
    FROM RecursiveTable
    --SELECT * FROM RecursiveTable WHERE Level = 0
    

    FURTHER EDIT:

    Okay, to do what you want, you can turn the query around; provided you know the page id:

    DECLARE @PageId int
    SET @PageId = 39;
    WITH RecursiveTable (PageId, PageName, PageInternalLink, PageInternalLinkUrl, PageInheritance, Level)
    AS(
       --Anchor
        SELECT      tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance,  0 AS Level
        FROM TestPage AS tt
        WHERE PageId = @PageId
        UNION ALL
       --Recursion
        SELECT tt.PageId,  tt.PageName, tt.PageInternalLink, tt.PageInternalLinkUrl, tt.PageInheritance, Level + 1
        FROM TestPage AS tt
        INNER JOIN RecursiveTable rt ON rt.PageInheritance = tt.PageId
    )
    SELECT * FROM RecursiveTable ORDER BY Level DESC
    

    What we do here is start off at the page you are on, then work backwards through the table looking for all parents. In this instance, the record with the highest level is the ultimate parent, so we order by level in descending order to reflect this.