Introduction
A Hierarchical Data is a data that is organized in a tree-like structure and structure allows information to be stored in a parent-child relationship with one-to-many relation records. This data can be stored either in a single table or different database tables with a parent-child relationship using foreign key.
 
The table structure shows the raw data stored in a database table. The column EmpNo is the primary unique key field and the column ReportsTo is the field we are going to refer as foreign key, by which the records are related to each other. There is lot of ways to do this concept, but we always prefer a simple and easiest way to achieve this
  For demonstration purpose, we are going to create Organizational Structure of a Company, which involves a Director, Manager, Sales Manager, Purchase Manager and other subordinate staffs. So we create table named as “Designation”, with 4 columns such as EmpNo, Designation, ReportsTo and Level. First three fields such as EmpNo, Designation and ReportsTo are self-explanatory. The last field Level is the rank of the designation in the Organization with 0 as its starting index. The Director of the company enjoys the top most position that he/she doesn’t need to report any one, so we input the level as 0, all the Managers of the company will come under Director, thus the level is 1, the department Managers such as Sales and Purchase will come under Manager, thus the level is 2 and the staff under them will be on level 3 and so on. Likewise, you can keep on increment the level based on rank of the Designation. Basically this column is used for creating a tree-like structure.
Setup the Repeater Control:


In the aspx page, drag and drop a Repeater
control, then go to the html source of this page, add the ItemTemplate
in between the Repeater tag, then add an Asp.Net
Table control from the toolbox.

<asp:Repeater ID="Repeater1"
runat="server" OnItemDataBound="Repeater1_ItemDataBound">

 <ItemTemplate>

    <asp:Table ID="Table1" runat="server"></asp:Table>

 </ItemTemplate>
</asp:Repeater>
Setup the Code-Behind:



The code-behind for this concept needs some attention, as it explains you the way
to display the data in the database in a Hierarchical or tree-like structure. Let
us go step by step.

Step 1: Add the SqlClient namespace in the code-behind
as follows,

using System.Data.SqlClient;

Step 2: In the Page_Load event, you have to retrieve the
data from the database and store it in a DataTable,

DataTable dt = new DataTable();

string sql = "Select * from Designation";

SqlDataAdapter da = new
SqlDataAdapter(sql,
ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());

da.Fill(dt);

Step 3: Add the DataTable to a DataSet to add relationship
between the columns in later stages.

DataSet Ds = new DataSet();

Ds.Tables.Add(dt);

Step 4: Now create two DataColumn objects, one for Primary
Key with the “EmpNo” column and one for Foreign Key with “ReportsTo” column from
the DataTable.

DataColumn PriKey = new DataColumn();

PriKey = dt.Columns["EmpNo"];

DataColumn ForKey = new DataColumn();

ForKey = dt.Columns["ReportsTo"];

Step 5:
Create a DataRelation object,
binding
both the Primary Key “PriKey” and Foreign
Key “ForKey” columns and name the relation as “ParentChild”.

 DataRelation dataRel = new DataRelation("ParentChild", PriKey, ForKey, false);

Step 6: Very Important, we need this DataRelation object
“dataRel” to be nested, since we don’t know the number of levels it is going to
contain.

 dataRel.Nested = true;

Step 7: Finally, we need to add this relationship to the
DataSet as follows,

 Ds.Relations.Add(dataRel);
 
So the DataSet is ready with relationship and next we need to bind the DataSet with
the Repeater control. As per the concept of this article, we are going to display
the data in an hirerchical structure. For this we need to do some code to achive
this.

As we know only the initial
level, but we have no idea of the final level, since
there can be any number of level
or even it can be infinity. So the best way is to loop through the rows
is by a recursive methods. This recursive method will retrieve
the record by record till its
last level and store every record in a DataTable that
can be referred by its memory
location rather than its value.

Let us start, by writing a recursive method to retrieve the record and store it
in a DataTable, which is accessed by its reference rather than its value.

 
private void GetChildObjects(DataRow[] drChild, ref DataTable dtFinal)

{

  foreach (DataRow childRow in drChild) 
  { 
    dtFinal.ImportRow(childRow); 
    GetChildObjects(childRow.GetChildRows("ParentChild"), ref
dtFinal); 
  }

}

The above method GetChildObjects, has two
parameters, the first one is the array
of DataRow and the second is the “ref” DataTable which is going to have the records.
Please note the “ref” keyword before the parameter declaration. This DataTable is
responsible to hold the records to binding. Inside this method, we loop through
the records of the DataRow arrays and we import record by record to the “ref” DataTable.
Then again we call the same method GetChildObjects, to loop through its child rows.
If there is no child rows, then execution will be stopped and no further call to
this method will be made.

Now, we are going to write another method to kick off the GetChildObjects methods,
as follows,

private DataTable GetParentObjects(DataTable dtMain)

{

  DataTable dtFinal = dtMain.Clone()
  foreach (DataRow parentRow in dtMain.Select("ReportsTo is null")) 
  { 
    dtFinal.ImportRow(parentRow); 
    GetChildObjects(parentRow.GetChildRows("ParentChild"), ref
dtFinal); 
  } 
  return dtFinal;

}
 
 
The above GetParentObjects method, takes a DataTable parameter, which can be the
DataTable that holds the data from the database. Inside this method, we create a
local DataTable object as “dtFinal” by cloning from the input parameter’s DataTable.
The “Clone” method, simply copies the structure of the DataTable without the data.
Next we are going to loop through the records in the incoming DataTable, and as
we know the top level record in the database will have the ReportsTo field as null,
we are going to start the loop from this record. If there are more than one record
with ReportsTo as null, then this loop will run that many times. So we find the
first record with ReportsTo as null, then import it into the “dtFinal” DataTable
using the ImportRow method. Then we call the GetChildObjects method by passing child
records of the current parent record and “dtFinal” DataTable which is passed by
reference.

This is the starting point to the GetChildObjects method. Since we have nested the
DataSet, the recusive method will run continuously till the last record to find
its related child records.

 

Step 8: The last step in the Page_Load event, is to bind
the Repeater control by calling the GetParentObjects as follows. Note that the argument
passed to the GetParentObjects method is the DataSet’s first Table, not the DataTable
object.

Repeater1.DataSource = GetParentObjects(Ds.Tables[0]);

Repeater1.DataBind();

The complete code of the Page_Load event is as follows,

protected void Page_Load(object sender, EventArgs e)

{

  if (!IsPostBack) 
  { 
    DataTable dt = new DataTable(); 
    string sql = "Select * from Designation"; 
    SqlDataAdapter da = new
SqlDataAdapter(sql,
ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()); 
    da.Fill(dt);

DataSet Ds = new DataSet(); 
    Ds.Tables.Add(dt);

DataColumn PriKey = new DataColumn(); 
    PriKey = dt.Columns["EmpNo"]; 
    DataColumn ForKey = new DataColumn(); 
    ForKey = dt.Columns["ReportsTo"];

DataRelation dataRel = new DataRelation("ParentChild", PriKey, ForKey,
false);

dataRel.Nested = true;

Ds.Relations.Add(dataRel);

Repeater1.DataSource = GetParentObjects(Ds.Tables[0]); 
    Repeater1.DataBind(); 
  }

}

Setup Asp.Net Table Control to display the Hierarchy structure



To display the data in a Hierarchical structure, we need to code in the ItemDataBound
event of the repeater control as follows.

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)

{

  if (e.Item.ItemType ==
ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
  { 
    Table Table1 = (Table)e.Item.FindControl("Table1"); 
    Table1.Width = Unit.Percentage(30); 
    Table1.BorderStyle = BorderStyle.Solid; 
    Table1.BorderWidth = Unit.Pixel(1); 
    Table1.CellPadding = 0; 
    Table1.CellSpacing = 0;

TableRow tblRow = new TableRow();

TableCell tblEmptyCell = new TableCell(); 
    tblEmptyCell.Controls.Add(new LiteralControl(String.Empty)); 
    tblEmptyCell.Width =

        Unit.Percentage(20 *

Convert.ToInt32(((DataRowView)(e.Item.DataItem))["Level"].ToString())); 
    tblRow.Cells.Add(tblEmptyCell);

TableCell tblCell = new TableCell(); 
    tblCell.Controls.Add(new

LiteralControl(((DataRowView)(e.Item.DataItem))["Designation"].ToString())); 
    tblCell.HorizontalAlign = HorizontalAlign.Left; 
    tblRow.Cells.Add(tblCell); 
    Table1.Rows.Add(tblRow);

  }

}

The above code is simple as its need no detail explanation. First we find the Table
control inside the Repeater control using its FindControl method, then we customize
the Table control by setting its properties such as Width, BorderStyle, BorderWidth,
CellPadding and CellSpacing. Next we create a TableRow to add to the Table control
and two TableCell objects, that is to be added to the TableRow. The first TableCell
object “tblEmptyCell” is responsible to create a tree-like structure by indenting
with an empty string and the width is calculated based on the Level field from the
database. The second TableCell object “tblCell”, is used to display the Designation
value for every record.

Now save all and press the “F5” button, the browser will popup, you can see the
data displayed in a hierarchical structure. You can customise the ItemDataBound
event as your wish to alter the look and feel of the display.                         

asp.net Hierarchical Data的更多相关文章

  1. mysql 树形数据,层级数据Managing Hierarchical Data in MySQL

    原文:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ 引言 大多数用户都曾在数据库中处理过分层数据(hiera ...

  2. Managing Hierarchical Data in MySQL

    Managing Hierarchical Data in MySQL Introduction Most users at one time or another have dealt with h ...

  3. 自定义 ASP.NET Identity Data Model with EF

    One of the first issues you will likely encounter when getting started with ASP.NET Identity centers ...

  4. Managing Hierarchical Data in MySQL(邻接表模型)[转载]

    原文在:http://dev.mysql.com/tech-resources/articles/hierarchical-data.html 来源: http://www.cnblogs.com/p ...

  5. 基于ASP.NET Core Data Protection生成验证token

    ASP.NET Core Data Protection 不仅提供了非对称加密能力,而且提供了灵活的秘钥存储方式以及一致的加解密接口(Protect与Unprotect).Session中用到了它,C ...

  6. Hierarchical data in postgres

    https://coderwall.com/p/whf3-a/hierarchical-data-in-postgres --------------------------------------- ...

  7. 集群环境下,你不得不注意的ASP.NET Core Data Protection 机制

    引言 最近线上环境遇到一个问题,就是ASP.NET Core Web应用在单个容器使用正常,扩展多个容器无法访问的问题.查看容器日志,发现以下异常: System.Security.Cryptogra ...

  8. CS0016: 未能写入输出文件“c:\windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\data\34aae060\b7daa87d\App_Web_addadvice.aspx.cdcab7d2.ekhlcbjd.dll”--“目录名无效。 ”

    产生原因: 应用程序运行时产生的临时文件需要存放到c:"windows"temp 文件夹下 而运行基于microsoft .net framework 框架下的应用程序 需要对te ...

  9. ASP.NET Core 数据保护(Data Protection 集群场景)【下】

    前言 接[中篇],在有一些场景下,我们需要对 ASP.NET Core 的加密方法进行扩展,来适应我们的需求,这个时候就需要使用到了一些 Core 提供的高级的功能. 本文还列举了在集群场景下,有时候 ...

随机推荐

  1. DELPHI 数学函数+字符处理函数

    System单元 Trunc(1234.5678);{1234} Trunc(-1234.5678);{-1234} Round(1234.5678);{1235} Round(-1234.5678) ...

  2. hdoj 1402 Prepared for New Acmer【快速幂】

    Prepared for New Acmer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/O ...

  3. python os.path模块--转载

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...

  4. Sql Server 带参数的存储过程执行方法

    Sql Server 带参数的存储过程执行方法 Visual C# 动态操作 SQL Server 数据库实例教程(4):带参数的存储过程执行方法 上一篇文章介绍了带参数的SQL语句执行方法和不带参数 ...

  5. Java基础学习中一些词语和语句的使用

    在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...

  6. http://oncenote.com/2015/09/16/Security-2-HTTPS2/ (轉載)

    上一篇<iOS安全系列之一:HTTPS>被CocoaChina转载,还顺便上了下头条: 打造安全的App!iOS安全系列之 HTTPS,但那篇文章只是介绍了比较偏应用的初级知识,对于想要深 ...

  7. 【50】了解new和delete的合理替换时机

    1.有时候,我们替换掉编译器提供的new或者delete.首先思考,为什么想要替换?下面是三个常见理由: a.用来检测运用上的错误,超额分配一些内存,再额外的空间放置一些内存: b.为了强化效能,编译 ...

  8. 传微软欲收购Xamarin:未来有望通过VS开发iOS和Android应用?

    据CRN报道,其援引匿名人士的消息称,微软将收购一家创建C#移动应用工具的公司或进行注资,并且谈判已经到了最终阶段.这家公司的名字叫做Xamarin,创建于2011年.对于微软来说,收购Xamarin ...

  9. WordPress Import 上传的文件尺寸超过php.ini中定义的upload_max_filesize值--&gt;解决方法。

    參考一: WordPress Importer上传导入备份文件时遇到这样一个错误,提示"上传的文件尺寸超过 php.ini 中定义的 upload_max_filesize 值". ...

  10. iOS开发——高级技术&广告功能的实现

    广告功能的实现 iPhone/iPad的程序,即使是Free的版本,也可以通过广告给我们带来收入.前提是你的程序足够吸引人,有足够的下载量.这里,我将介绍一下程序中集成广告的方法.主要有两种广告iAd ...