1.3 菜单管理 (系统开发架构与设计步步谈)
2011-03-02 11:43
561 查看
1.3 菜单管理
一个系统开发一段时间以后,或者用户试用一段时间以后,会发现,原来有些页面不用了,有些菜单不需要了。在我们开发过程中都会有开发环镜、测试环镜、正式环镜,如果菜单条目经常变动,保持菜单及文件在各个环镜同步是个比较麻烦的事情,特别是那些前期项目需求分析的不到位的项目,一会删掉一个,一会新增一个。对此我们的系统需要额外的辅助工具来做这件事情
通常情况下,菜单表都设计为自关联表,如下表
此处的id不可用自增的形式,应为程序生成的序列号,以方便日后生成菜单脚本
一般C#程序显示菜单示例代码为,源自《ASP.NET2.0 Unleashed》
/// <summary>
/// Get the data from the database and create the top-level
/// menu items
/// </summary>
private void PopulateMenu()
{
DataTable menuData = GetMenuData();
AddTopMenuItems(menuData);
}
/// <summary>
/// Use a DataAdapter and DataTable to grab the database data
/// </summary>
/// <returns></returns>
private DataTable GetMenuData()
{
// Get Categories table
string selectCommand = "SELECT CategoryId,ParentId,Name FROM Categories";
string conString = WebConfigurationManager.ConnectionStrings["Categories"].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter(selectCommand, conString);
DataTable dtblCategories = new DataTable();
dad.Fill(dtblCategories);
return dtblCategories;
}
/// <summary>
/// Filter the data to get only the rows that have a
/// null ParentID (these are the top-level menu items)
/// </summary>
private void AddTopMenuItems(DataTable menuData)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID IS NULL";
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
Menu1.Items.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
/// <summary>
/// Recursively add child menu items by filtering by ParentID
/// </summary>
private void AddChildMenuItems(DataTable menuData, MenuItem parentMenuItem)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID=" + parentMenuItem.Value;
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
parentMenuItem.ChildItems.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
自关联表需要递归算法。
到这里实现了菜单的设计,还没有解决开始提出来的问题,保持测试环镜、正式环镜同步。实现的思路很多,我这里想说的就有两种。
一种是不用数据库设计菜单了,而是所有菜单只保存在一个XML文件中,每次变更只需要变更XML文件即可,去更新测试环镜、生产环镜也只要更新一个菜单文件即可
另一种用数据库设计菜单,如果由于设计变更,删除以前的菜单和新增了新的菜单,可以做门的开发辅助工具完成,再针对目前的菜单生成SQL脚本,用脚本来更新测试、生产环镜,如果开发辅助工具要是做的更好,可以专门在项目里做个页面来做更新菜单功能。更新的思路是删除以前的菜单,然后再完整新增菜单条目。生成脚本的存储过程可以参考我以前的日志 《SQL Server 2008 生成数据脚本》
一个系统开发一段时间以后,或者用户试用一段时间以后,会发现,原来有些页面不用了,有些菜单不需要了。在我们开发过程中都会有开发环镜、测试环镜、正式环镜,如果菜单条目经常变动,保持菜单及文件在各个环镜同步是个比较麻烦的事情,特别是那些前期项目需求分析的不到位的项目,一会删掉一个,一会新增一个。对此我们的系统需要额外的辅助工具来做这件事情
通常情况下,菜单表都设计为自关联表,如下表
字段名 | 类型 | |
Id | Varchar(20) | |
Parented | Varchar(20 | |
url | Varchar(50) | |
isUsed | bit |
一般C#程序显示菜单示例代码为,源自《ASP.NET2.0 Unleashed》
/// <summary>
/// Get the data from the database and create the top-level
/// menu items
/// </summary>
private void PopulateMenu()
{
DataTable menuData = GetMenuData();
AddTopMenuItems(menuData);
}
/// <summary>
/// Use a DataAdapter and DataTable to grab the database data
/// </summary>
/// <returns></returns>
private DataTable GetMenuData()
{
// Get Categories table
string selectCommand = "SELECT CategoryId,ParentId,Name FROM Categories";
string conString = WebConfigurationManager.ConnectionStrings["Categories"].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter(selectCommand, conString);
DataTable dtblCategories = new DataTable();
dad.Fill(dtblCategories);
return dtblCategories;
}
/// <summary>
/// Filter the data to get only the rows that have a
/// null ParentID (these are the top-level menu items)
/// </summary>
private void AddTopMenuItems(DataTable menuData)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID IS NULL";
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
Menu1.Items.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
/// <summary>
/// Recursively add child menu items by filtering by ParentID
/// </summary>
private void AddChildMenuItems(DataTable menuData, MenuItem parentMenuItem)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID=" + parentMenuItem.Value;
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
parentMenuItem.ChildItems.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
自关联表需要递归算法。
到这里实现了菜单的设计,还没有解决开始提出来的问题,保持测试环镜、正式环镜同步。实现的思路很多,我这里想说的就有两种。
一种是不用数据库设计菜单了,而是所有菜单只保存在一个XML文件中,每次变更只需要变更XML文件即可,去更新测试环镜、生产环镜也只要更新一个菜单文件即可
另一种用数据库设计菜单,如果由于设计变更,删除以前的菜单和新增了新的菜单,可以做门的开发辅助工具完成,再针对目前的菜单生成SQL脚本,用脚本来更新测试、生产环镜,如果开发辅助工具要是做的更好,可以专门在项目里做个页面来做更新菜单功能。更新的思路是删除以前的菜单,然后再完整新增菜单条目。生成脚本的存储过程可以参考我以前的日志 《SQL Server 2008 生成数据脚本》
相关文章推荐
- 系统开发管理、架构与设计步步谈随笔索引
- 从架构设计到系统实施-基于.NET 3.0的全新企业应用之开发基于MMC 3.0的管理工具
- 1.1 编码规范(系统开发架构与设计步步谈)
- 开源软件项目管理系统招设计/开发。。。。。Zend Framework2架构 svn://735.ikwb.com/pms
- 1.2 User Interface 规范(系统开发架构与设计步步谈)
- [课程设计]Scrum 1.3 多鱼点餐系统开发进度(系统主界面框架&美化)
- 会员管理系统的设计和开发(1)
- Unity项目架构设计与开发管理
- 【分享】一个通用强大的主数据管理系统(架构设计讲解及源码下载)
- 企业管理软件开发架构之七 Object Control设计与运用
- [Unity] Unity项目架构设计与开发管理 - 视频观看记录
- 深入浅出MongoDB应用实战开发(基础、开发指南、系统管理、集群及系统架构)
- web工作流管理系统开发之三 可视化流程设计器
- 升讯威微信营销系统开发实践:(2)功能设计与架构设计
- 【学习日记】MVC架构+DAO设计小型信息管理系统(一)
- 基于整合了struts 和hibernate 的j2ee 架构的用户权限管理系统的设计与实现
- DBUtils框架+客户管理系统的设计与开发
- Android 开发基础课程设计---手机文件管理系统
- 南宁供电局抄表及电量电费管理系统的开发设计
- 用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建