本文介紹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; } }
實現效果圖:
本文配套源碼