ASP.NET Web开发框架之 数据库文档方法

随着项目的进度推进,数据库的表越来越多,字段也频繁的变更。如何对这些变更作出文档说明,既要方便,又要有可维护性。比如,可以为所有的表创建WORD文档来说明,各个表的含义和字段的意义,但是如果数据库表或字段变更频繁的话,更新WORD文档是个相对麻烦的工作。在博客园中曾经有技术人员专门创建文档生成工具,以程序的方式直接生成WORD文档,使为数据库创建文档的可行性提高很多,轻松点击鼠标就可以做完的工作,非常容易。

SQL Doc

推荐给各位的数据库文档工具箱中,排名第一的是RedGate公司的SQL Doc。

image

创建新项目,连接数据库服务器,选择数据库,在右边的窗格中为表或它的字段创建描述信息。

使用SQL Profiler查询跟踪器,检测到它进行如下的SQL语句

  
  
  1. exec sp_executesql N'if (SELECT count(*)   
  2. FROM ::fn_listextendedproperty (@propertyName, @myLevel0Type, @myLevel0Name, @myLevel1Type, @myLevel1Name, @myLevel2Type, @myLevel2Name))> 0   
  3. begin   
  4.     EXEC sp_updateextendedproperty  @propertyName, @propertyValue, @myLevel0Type, @myLevel0Name, @myLevel1Type, @myLevel1Name, @myLevel2Type, @myLevel2Name;   
  5. end   
  6. else   
  7. begin   
  8.     EXEC sp_addextendedproperty @propertyName, @propertyValue, @myLevel0Type, @myLevel0Name, @myLevel1Type, @myLevel1Name, @myLevel2Type, @myLevel2Name;   
  9. end',N'@propertyName nvarchar(14),@myLevel0Type nvarchar(6),@myLevel0Name nvarchar(3),@myLevel1Type nvarchar(5),@myLevel1Name nvarchar(10),@myLevel2Type nvarchar(6),@myLevel2Name nvarchar(6),@propertyValue nvarchar(4)',@propertyName=N'MS_Description',@myLevel0Type=N'SCHEMA',@myLevel0Name=N'dbo',@myLevel1Type=N'TABLE',@myLevel1Name=N'ADBBSYSMSG',@myLevel2Type=N'COLUMN',@myLevel2Name=N'RECNUM',@propertyValue=N'记录编号' 

它使用附加属性的方式,为表或字段创建备注信息,直接存放在数据库中。

回到SQL Server Management Studio中查看,看到它直接附加在字段的扩展属性中。

image

方便的地方不仅仅在这里,当你右键点击表,以Script Table As生成表的创建脚本时,它的最后一行,会添加属性

  
  
  1. CREATE TABLE [dbo].[ADBBSYSMSG](  
  2.     [RECNUM] [int] IDENTITY(1,1) NOT NULL,  
  3.     [SYSMSG_ID] [nvarchar](16) NOT NULL,  
  4.     [MESSAGE] [nvarchar](255) NOT NULL,  
  5.     [CREATED_DATE] [datetime] NOT NULL,  
  6.     [CREATED_BY] [nvarchar](10) NOT NULL,  
  7.     [REVISED_DATE] [datetime] NOT NULL,  
  8.     [REVISED_BY] [nvarchar](10) NOT NULL,  
  9.  CONSTRAINT [PK_ADBBSYSMSG] PRIMARY KEY CLUSTERED   
  10. (  
  11.     [SYSMSG_ID] ASC 
  12. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 70) ON [PRIMARY]  
  13. ON [PRIMARY]  
  14. GO  
  15. EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'记录编号' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'ADBBSYSMSG', @level2type=N'COLUMN',@level2name=N'RECNUM' 
  16. GO 

到目前为止,这是我发现的最优秀的数据库文档工具。新的2.1版本支持SQL Server 2008 R2。

Management Table Description

在没有找到SQL Doc之前,我一直寻找一种方法能为数据库创建文档,又便于维护。经过摸索,自己创建了如下工具,以维护数据库文档。

image

这个工具的原理,和上面的SQL Doc一样,也是运用扩展属性。关键部分的C#代码如下所示

  
  
  1.    string tablesql = @"  if(select count(1) from fn_listextendedproperty(N'MS_Description'," +  
  2.   "   N'SCHEMA',N'{2}',N'TABLE',N'{0}',NULL,NULL))>0 " +  
  3.  "    EXEC sp_updateextendedproperty N'MS_Description',N'{1}', " +  
  4.  "    N'SCHEMA',N'{2}', N'TABLE',N'{0}',NULL,NULL  " +  
  5.  "   ELSE   " +  
  6. "   EXEC sp_addextendedproperty  N'MS_Description',N'{1}', " +  
  7. "  N'SCHEMA',N'{2}',N'TABLE',N'{0}'   ";  
  8.  
  9.        //更新字段的描述 {2} 默认是dbo,但是AdventureWorks出现大量不是dbo的情况  
  10.        string fieldSql=@"if(select count(1) from fn_listextendedproperty(N'MS_Description',N'SCHEMA', "+  
  11.       " N'{3}',N'TABLE',N'{0}',N'COLUMN', N'{1}'))>0   "+  
  12.       " EXEC sp_updateextendedproperty N'MS_Description',N'{2}',  "+  
  13.       "    N'SCHEMA',N'{3}', N'TABLE',N'{0}',N'COLUMN', N'{1}'  "+  
  14.       "  ELSE   "+  
  15.       "  EXEC sp_addextendedproperty  N'MS_Description',N'{2}', "+  
  16.        "      N'SCHEMA',N'{3}',N'TABLE',N'{0}',N'COLUMN', N'{1}'   ";  
  17.  
  18.        //读取表的描述  
  19.        string getTableDescription = " select value from  " +  
  20.        " fn_listextendedproperty(N'MS_Description',N'SCHEMA',N'{1}',N'TABLE'," +  
  21.        " N'{0}',NULL, NULL)  ";  
  22.  
  23.        //读取字段的描述  
  24.        string getFieldDescription=" select objname,value from  "+  
  25.        " fn_listextendedproperty(N'MS_Description',N'SCHEMA',N'{1}',N'TABLE',"+  
  26.        " N'{0}',N'COLUMN', NULL)  "

tableSql是对表进行注释,添加扩展属性,fieldSql是对字段添加扩展属性,下面的两行分别用于读取。整个工具,最关键的部分也是这里,这些是我用查询跟踪器,跟踪出来的。尽管可以直接用SQL Server Management Studio直接完成这个工作,但是没有这个小工具直观,把这些做成工具,方便维护。

Custom Table 自定义表

这种方法比较保守,也很稳定。在数据库中专门创建数据表,来存放表及其字段的含义,再设计工具对此进行更新和维护。以金蝶系统为例子,它就是应用这个方法。

要查询表及其字段的文档信息,需要执行如下的语句

  
  
  1. select * from t_tabledescription   
  2. select * from t_fielddescription  

--要查具体的某张表描述,执行该语句:

  
  
  1. select * from t_fielddescription where FTableID=(select FTableID from t_tabledescription where FTableName='t_Item')  

clip_image001 

此外,金碟的辅助工具,查看表描述信息,也做的简单实用。

image

金碟的产品线众多,不同产品数据表的用途会有差异,比如这里的适用于服装鞋帽版。

这种方法简单直观,直接在表中存放描述信息。需要提供更新工具,读取查看工具,如果能导出成WORD/EXCEL那就更加完美了。

原文链接:http://www.cnblogs.com/JamesLi2015/archive/2012/09/29/2708000.html

【编辑推荐】

  1. 经过前面六篇文章的讲解,基本的理论已经介绍完毕,这一篇进行实战练习,讨论如何从头开始开发一个完整的ASP.NET 页面,并进行数据读写,业务逻辑设定。

    1 设计数据库表 Table Design

    公司表存放系统中的公司实例,表示进行业务往来的实体,它的表结构如下脚本所示

        
        
    1. CREATE TABLE [dbo].[Company](  
    2.     [CompID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,  
    3.     [ParentCompID] [numeric](18, 0) NULL,  
    4.     [CompTypeID] [numeric](18, 0) NOT NULL,  
    5.     [CompNO] [varchar](20) NOT NULL,  
    6.     [CompName] [varchar](50) NOT NULL,  
    7.     [Corporation] [varchar](20) NULL,  
    8.     [CorpMobile] [varchar](20) NULL,  
    9.     [CorpTel] [varchar](20) NULL,  
    10.     [Address] [varchar](100) NULL,  
    11.     [Tel1] [varchar](20) NULL,  
    12.     [Tel2] [varchar](20) NULL,  
    13.     [Fax] [varchar](20) NULL,  
    14.  CONSTRAINT [PK_TCOMPANY] PRIMARY KEY CLUSTERED   
    15. (  
    16.     [CompID] ASC 
    17. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ONON [PRIMARY]  
    18. ON [PRIMARY

    2 实体映射 ORM Mapping

    打开LLBL Gen,连接到数据库并更新实体,把上面的Company表映射到实体CompanyEntity。设计字段名时,最好以简明,可读性好的词命名,这样可以增强映射到实体上的属性的可读性。

    image

    如果表与表之前有关联,LLBL Gen会自动生成表之间的关联。

    3 数据读写接口与实现的产生 Interface and Service Implementation

    这一步骤也是自动化的,不需要额外的脑力活动。以Code Smith打开模板Interface.cst和Manager.cst,选择表对象为Company,生成代码,把这此代码拷贝到Visual Studio的项目中即可。

    image

    请在项目的Source\Maintenance\Template路径下获取上面所提到的两个模板,用以生成数据读写接口与实现代码。

    4  ASP.NET 页面布局与编程 ASP.NET Page Layout Design and Coding

    向Web项目中添加一个ASP.NET 页面,命名为company.aspx。我推荐以小写命名Web项目的文件夹,文件名和页面类型名称。为了让它具备EntryPageBase的功能,我在页面的首部,添加一个Toolbar,它用来承载工具箱中的系列工具,以进行数据的前后浏览,增加删除工作。其它的地方,以FormRow的方式安排布局。

    image

    FormRow会为它的Items平均分配宽度,所以每行FormRow最好放置相同的Items以让界面布局看起来美观整齐。

    ASP.NET的后台代码看起来是这样的,这里罗列所有的代码,供您参考。

        
        
    1. [Function("AIITHD""~/module/company.aspx")]  
    2. public partial class company : EntryPageBase  
    3. {       
    4.         protected override void PageLoadEvent(object sender, EventArgs e)  
    5.         {  
    6.             if (!IsPostBack)  
    7.             {  
    8.                 TransactionType = EntityType.CompanyEntity;  
    9.                 ddlCompanyGroup.InitializeValueListFromEnum(9);  
    10.             }  
    11.             base.PageLoadEvent(sender, e);  
    12.         }  
    13.  
    14.         public override EntityBase2 LoadEntity(string refNo)  
    15.         {  
    16.             ICompanyManager manager = ClientProxyFactory.CreateProxyInstance<ICompanyManager>();  
    17.             CompanyEntity customer = manager.GetCompany(Convert.ToInt16(refNo));  
    18.             return customer;  
    19.         }  
    20.  
    21.         public override void DeleteEntity(EntityBase2 entity)  
    22.         {  
    23.             CompanyEntity user = (CompanyEntity)entity;  
    24.             ICompanyManager manager = ClientProxyFactory.CreateProxyInstance<ICompanyManager>();  
    25.             manager.DeleteCompany(user);  
    26.         }  
    27.  
    28.         public override void SaveEntity(EntityBase2 entity)  
    29.         {  
    30.             CompanyEntity user = (CompanyEntity)entity;  
    31.             ICompanyManager manager = ClientProxyFactory.CreateProxyInstance<ICompanyManager>();  
    32.             manager.SaveCompany(user);  
    33.         }      

    首先给页面分配一个功能编码,比如此页面的AIITHD,然后设定的Url属性,这两个同时附加到页面的特性中去。

        
        
    1. [Function("AIITHD""~/module/company.aspx")] 

    这里有些不足之处,到目前为止我还没有找到根据ASP.NET页面类型,得到它的页面文件。因为ASP.NET的请求处理是以ASPX文件在浏览器中敲入后,发送到服务器来执行的。所以,如果能找到这个办法,则这里的Url设定可以省略。

    其次,指定TransactionType = EntityType.CompanyEntity,这用来指定当前页面的实体为CompanyEntity,并对它进行读写操作,与页面相关的数据绑定,回写到数据库中,均需要此属性。紧接着的是三个模板方法,LoadEntity用于加载公司实体,DeleteEntity用于删除,SaveEntity用于保存修改后的实体。这三个方法均是override,它被页面基类调用。

    最后执行一下功能编码为AIITHD的功能,来看看效果是怎样的。在页面的右上角输入功能编码,点击Go按钮。

    image

    关于数据绑定,所有的秘密藏在页面文件中,我以Company No为例子,请看它的页面文件

        
        
    1. <ext:TextBox ID="tbxName" runat="server" Label="Company No" DataBindingString="CompanyEntity:CompNo">  
    2.                    </ext:TextBox> 

    它的DataBindingString属性,在读取数据时,将实体属性绑定到此控件,在保存时,又读取这个值,回写到实体中并保存到数据库中,这样可以减少大量重复的代码。

    原文链接:http://www.cnblogs.com/JamesLi2015/archive/2012/10/08/2714794.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值