CREATE TABLE TB_MENU (
id INT PRIMARY KEY IDENTITY,
names NVARCHAR(50) NOT NULL, -- 選單顯示文字
page NVARCHAR(200), -- 導向網址
treeId INT DEFAULT 0, -- 父選單 ID,0 表示根節點
position INT DEFAULT 0 -- 根節點顯示順序
);
treeId 為自我參考外鍵,構建樹狀結構。
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) BuildMenu();
}
private void BuildMenu()
{
string connStr = "Server=.;Trusted_Connection=SSPI;Database=MENUDB";
using (SqlConnection cn = new SqlConnection(connStr))
{
cn.Open();
// 取得根節點
SqlCommand cmd = new SqlCommand(
"SELECT * FROM TB_MENU WHERE treeId = 0 ORDER BY position", cn);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
MenuItem root = new MenuItem
{
Text = dr["names"].ToString(),
Value = dr["id"].ToString(),
NavigateUrl = dr["page"].ToString(),
Enabled = true
};
Menu1.Items.Add(root);
AddChildMenus(root, cn, Convert.ToInt32(dr["id"]));
}
}
}
}
private void AddChildMenus(MenuItem parent, SqlConnection cn, int parentId)
{
SqlCommand cmd = new SqlCommand(
"SELECT * FROM TB_MENU WHERE treeId = @parentId", cn);
cmd.Parameters.AddWithValue("@parentId", parentId);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
MenuItem child = new MenuItem
{
Text = dr["names"].ToString(),
Value = dr["id"].ToString(),
NavigateUrl = dr["page"].ToString(),
Enabled = true
};
parent.ChildItems.Add(child);
// 遞迴處理下一層
AddChildMenus(child, cn, Convert.ToInt32(dr["id"]));
}
}
}
}
<asp:Menu ID="Menu1" runat="server" Orientation="Horizontal"
StaticDisplayLevels="2" MaximumDynamicDisplayLevels="5">
</asp:Menu>
DataTable,在記憶體中用 LINQ 遞迴建構樹狀結構,減少資料庫往返。OutputCache) 針對選單片段快取,降低每次請求的資料庫負載。