本文介紹Linq to sql在實際工程中的例子,利用TreeView,遞歸實現導航功能。
系統環境
Visual Studio 2010 +NET Framework 3.5+Microsoft SQL Server 2005+Window XP+ SP3
LINQ TO SQL采用配置式開發
開發實現
由於linq to sql屬於ORM屬於Bottom Up的ORM設計框架,結合TreeView特點。我們先設計數據庫。
數據庫設計觀察TreeView的Node的特點,一種是有子點,另外一種是葉子節點。我們設計的PDM模型如下:

有子點的Node對象對應模塊分類表,葉子節點Node對應模塊表。其中模塊分類表自身有1對多關系(一個模塊 分類可以繼續子分類),和模塊表是1對多關系(對各葉子節點模塊屬於同一個模塊分類)
生成表PB_MODULE_TYPE 的SQL(MS SQLSERVER 2005)如下:
USE [Test]
GO
/****** 對象: Table [dbo].[MODULE_TYPE] 腳本日期: 06/16/2009 17:05:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MODULE_TYPE](
[ID] [varchar](15) COLLATE Chinese_PRC_CI_AS NOT NULL,
[PARENT_ID] [varchar](15) COLLATE Chinese_PRC_CI_AS NULL,
[NAME] [varchar](40) COLLATE Chinese_PRC_CI_AS NOT NULL,
[REMARK] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,
[ORDER_ID] [int] NOT NULL,
CONSTRAINT [PK_PB_MODULE_TYPE] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [Test]
GO
ALTER TABLE [dbo].[MODULE_TYPE] WITH CHECK ADD CONSTRAINT
[FK_PB_MODULE_TYPE_PB_MODULE_TYPE] FOREIGN KEY([PARENT_ID])
REFERENCES [dbo].[MODULE_TYPE] ([ID])
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_NAME, PB_ORDER_ID) VALUES ('0000000001', '分類
1', 10)
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_PARENT_ID ,PB_NAME, PB_ORDER_ID) VALUES
('0000000011','0000000001', '分類11',11)
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_PARENT_ID ,PB_NAME, PB_ORDER_ID) VALUES
('0000000012', '0000000001','分類12', 12)
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_NAME,PB_ORDER_ID) VALUES ('0000000002', '分類2',
20)
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_NAME, PB_ORDER_ID) VALUES ('0000000003', '分類
3', 30)
INSERT INTO dbo.PB_MODULE_TYPE (PB_ID, PB_NAME, PB_ORDER_ID) VALUES ('0000000004', '分類
4', 40)
go
生成表PB_MODULE_TYPE 的SQL(MS SQLSERVER 2005)如下:
USE [Test]
GO
/****** 對象: Table [dbo].[MODULE] 腳本日期: 06/16/2009 17:06:41 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MODULE](
[ID] [varchar](15) COLLATE Chinese_PRC_CI_AS NOT NULL,
[MODULE_TYPE_ID] [varchar](15) COLLATE Chinese_PRC_CI_AS NOT NULL,
[TAG] [varchar](40) COLLATE Chinese_PRC_CI_AS NOT NULL,
[NAME] [varchar](40) COLLATE Chinese_PRC_CI_AS NOT NULL,
[MODULE_URL] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,
[REMARK] [varchar](200) COLLATE Chinese_PRC_CI_AS NULL,
[DISABLED] [int] NOT NULL,
[ORDER_ID] [int] NOT NULL,
CONSTRAINT [PK_PB_MODULE] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [Test]
GO
ALTER TABLE [dbo].[MODULE] WITH CHECK ADD CONSTRAINT [FK_PB_MODULE_PB_MODULE_TYPE1]
FOREIGN KEY([MODULE_TYPE_ID])
REFERENCES [dbo].[MODULE_TYPE] ([ID])
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000000', '0000000001', 'SysCodeMgr', '百度',
'www.ambow.com', 0, 10)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000001', '0000000001', 'ModuleMgr', '安博',
'www.ambow.com', 0, 20)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000002', '0000000011', 'RoleMgr', '軟件培訓',
'www.ambow.com', 0, 10)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000003', '0000000012', 'DepartmentMgr', '心心相映',
'', 0, 20)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000004', '0000000012', 'StaffMgr', '昆山安博軟件外包
產業園', 'www.ambow.com', 0, 30)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000005', '0000000002', 'ChangeMyPwd', '新浪',
'www.sina.com', 0, 10)
INSERT INTO dbo.PB_MODULE (PB_ID, PB_MODULE_TYPE_ID, PB_TAG, PB_NAME, PB_MODULE_URL,
PB_DISABLED, PB_ORDER_ID) VALUES ('0000000006', '0000000003', 'UserMgr', '雅虎',
'www.qq.com', 0, 10)
代碼實現
采用配置的方式進行Linq to SQL開發,生成DBML,命令如下 sqlMetal /conn:server=172.1.42.15;database=ZXKP;uid=sa;pwd=1 /DBML:D:\ZXKP.dbml /namespace:DMN /serialization:Unidirectional ,把生成的DBML文件加到你的工程中,生成的類圖如下:

對於采用敏捷方法開發的,數據庫可能經常微調,對於sqlMetal工具,我們可以讓輸出路徑就是你的工程中 的dbml文件路徑。另外sqlMetal對於輸出提供的可控制性太少,實體類屬性和你數據庫字段設計的一樣,所以你 在設計數據庫時候盡量編碼符合C#規范些。
遞歸實現代碼,首先找個Potal,加載根節點:
private void LoadModuleTree()
{
//獲取所有頂層模塊。
DMN.ZXKP context = new DMN.ZXKP();
//未審核的狀態
var topModuleType = from m in context.MODULE_TYPE
where m.PARENT_ == null
select m;
TreeNode TopNode = new TreeNode("功能模塊");
//增加模塊分類和模塊。
foreach (MODULE_TYPE mt in topModuleType)
{
TreeNode node = new TreeNode();
TopNode.ChildNodes.Add(node);
node.Text = mt.NAME;
node.ToolTip = mt.NAME;
AddSubNodes(node, mt);
node.Expanded = false;
}
tvMenu.Nodes.Add(TopNode);
}
遞歸加載其余節點:
private void AddSubNodes(TreeNode currentNode, MODULE_TYPE currentModuleType)
{
//增加子模塊分類
foreach (MODULE_TYPE mt in currentModuleType.MODULE_TYPE_MODULE_TYPE)
{
TreeNode subNode = new TreeNode();
currentNode.ChildNodes.Add(subNode);
subNode.Text = mt.NAME;
subNode.ToolTip = mt.NAME;
AddSubNodes(subNode, mt);
}
//增加模塊
foreach (MODULE m in currentModuleType.MODULE)
{
TreeNode nodeModule = new TreeNode();
currentNode.ChildNodes.Add(nodeModule);
nodeModule.Text = m.NAME;
nodeModule.ToolTip = m.NAME;
nodeModule.NavigateUrl = m.MODULE_URL;
}
}
實現效果圖:

本文配套源碼