中成网站建设
    成都做网站,就选中成网站建设!专业四川网站建设,成都网站建设服务提供商
            企业宣传网站建设、电子商务网站建设、OA办公系统。联系电话:028-66165255
    资讯列表  
 ASP.NET防止用户多次登录的方法…
 生成不重复的随机整数
 ASP.NET获取IP的6种方法
 ASP dot net 里的状态管理-Ses…
 判断获取的参数是否为null
 中文验证码生成实例
 微软发布第二个实验版的.Net 4…
 微软轻量级Web开发平台WebMatr…
 asp.net 生成图片验证码
 Asp.net直接保存文件到客户端
 .Net开发中的多线程编程总结
 C#中关于get和set的详细例子介…
 ASP.NET编程技巧:提高asp.net…
 asp.net 剪切 缩小图片原码
 截断过长字符串为省略号算法
    资讯详情  
打造你自己的代码生成器
发布时间:2009-10-27                  来源:成都网站建设--中成网建         【加入收藏】

网络上有很多的自动生成代码的工具,有基于模板的像MyGeneration、CodeSmith,有基于自己写的架构的像动软的,都是很好的代码生成工具。但是一般在公司里面我们都有自己的架构,所以如何基于自己的架构生成代码呢?如果你熟悉MyGeneration等工具的模板制作,就可以做个模板然后也可以生成代码。如果不熟悉这个模板工具,可能要花费一些时间来学习如何制作模板。
 我个人喜欢自己写点代码,不妨制作自己的代码生成器。


首先,我们需要有获取数据库、数据表信息的sql。(以下都已SQL2005为例)。
1、获取服务器上所有的数据库:select name as dbName from sysdatabases order by name
注意:此时的数据库连接字符串需要连接master库,因为所有的库信息都保存在系统库中。
2、获取库中所有表:
select [name] from sysObjects where xtype='U'and [name]<>'dtproperties' order by [name]
注意:此时的连接字符串中的库连接的是你要操作的库,已经不是master了。
3、获取表的字段信息:
SELECT colorder=C.column_id,ColumnName=C.name,TypeName=T.name, Length=C.max_length, Preci=C.precision, Scale=C.scale, IsIdentity=CASE WHEN C.is_identity=1 THEN N'1'ELSE N'' END,isPK=ISNULL(IDX.PrimaryKey,N''),Computed=CASE WHEN C.is_computed=1 THEN N'1'ELSE N'' END, IndexName=ISNULL(IDX.IndexName,N''), IndexSort=ISNULL(IDX.Sort,N''), Create_Date=O.Create_Date, Modify_Date=O.Modify_date, cisNull=CASE WHEN C.is_nullable=1 THEN N'1'ELSE N'' END, defaultVal=ISNULL(D.definition,N''), deText=ISNULL(PFD.[value],N'') FROM sys.columns C INNER JOIN sys.objects O ON C.[object_id]=O.[object_id] AND O.type='U' AND O.is_ms_shipped=0 INNER JOIN sys.types T ON C.user_type_id=T.user_type_id LEFT JOIN sys.default_constraints D ON C.[object_id]=D.parent_object_id AND C.column_id=D.parent_column_id AND C.default_object_id=D.[object_id] LEFT JOIN sys.extended_properties PFD ON PFD.class=1 AND C.[object_id]=PFD.major_id AND C.column_id=PFD.minor_id LEFT JOIN sys.extended_properties PTB ON PTB.class=1 AND PTB.minor_id=0 AND C.[object_id]=PTB.major_id LEFT JOIN ( SELECT IDXC.[object_id], IDXC.column_id, Sort=CASE INDEXKEY_PROPERTY(IDXC.[object_id],IDXC.index_id,IDXC.index_column_id,'IsDescending') WHEN 1 THEN 'DESC' WHEN 0 THEN 'ASC' ELSE '' END, PrimaryKey=CASE WHEN IDX.is_primary_key=1 THEN N'1'ELSE N'' END, IndexName=IDX.Name FROM sys.indexes IDX INNER JOIN sys.index_columns IDXC ON IDX.[object_id]=IDXC.[object_id] AND IDX.index_id=IDXC.index_id LEFT JOIN sys.key_constraints KC ON IDX.[object_id]=KC.[parent_object_id] AND IDX.index_id=KC.unique_index_id INNER JOIN ( SELECT [object_id], Column_id, index_id=MIN(index_id) FROM sys.index_columns GROUP BY [object_id], Column_id ) IDXCUQ ON IDXC.[object_id]=IDXCUQ.[object_id] AND IDXC.Column_id=IDXCUQ.Column_id AND IDXC.index_id=IDXCUQ.index_id ) IDX ON C.[object_id]=IDX.[object_id] AND C.column_id=IDX.column_id WHERE O.name=N'YourTablelName' ORDER BY O.name,C.column_id
这个sql有点超长,里面YourTablelName换成你自己的表名即可获得表的字段信息。


其次,现在我们就可以通过上面的三条基本的sql,就可以获得我们生成代码所需的信息,还等什么,开写。
封装一个简单的query。
public DataSet Query(string sqlStr)
{
 SqlDataAdapter sda = null;
 System.Data.SqlClient.SqlConnection sqlConn = new System.Data.SqlClient.SqlConnection();

 connStr = "Data Source=127.0.01;Initial Catalog=testDb;User ID=sa;Password=sa;";

 sqlConn.ConnectionString = connStr;
 try
 {
  DataSet ds = new DataSet();
  sda = new SqlDataAdapter(sqlStr,sqlConn);
  sda.Fill(ds);
  sda.Dispose();
  return ds;
 }
 catch(Exception e)
 {
  return null;
 }
 finally
 {
  sqlConn.Close();
 }
}
通过这个简单的query,我们就可以获得需要生成代码的表信息。


最后,通过循环DataSet中的信息,我们可以获得字段的名称、类型、长度、是否可空、是否主键、是否自增列、备注的相关信息,就可以按着我们的自己的架构来生成代码了。包括生成数据操作层,当然我们也可以按着自己的架构把aspx页面和aspx.cs等等都生成出来。因为aspx和aspx.cs无非就是纯文本文件,甚至我们也可以仿造动软的模式将项目的方案(sln)都生成出来,只要我们先打开这些文件,看看就明白了。

下面这段代码可以根据你自己的需要生成部分aspx页面,包括了必录控件和格式校验控件。
foreach (DataRow row1 in clmnInfoList.Rows)
{
 string clmnName = row1["ColumnName"].ToString();
 string clmnTypeName = row1["TypeName"].ToString();
 string isIdentity = row1["IsIdentity"].ToString();
 string clmnLen = row1["Length"].ToString();
 string clmnPreci = row1["Preci"].ToString();
 string clmnScale = row1["Scale"].ToString();
 string isPkClmn = row1["isPK"].ToString();
 string allowNull = row1["cisNull"].ToString();
 string defaultVal = row1["defaultVal"].ToString();
 string desc = row1["deText"].ToString();

 //跳过自增类
 if(isIdentity.Equals("1"))
 {
  continue;
 }

 templateStr += "          <TR>\r\n";
 templateStr += "           <TD height=\"25\" align=\"right\" width=\"25%\">\r\n";
 templateStr += "            <asp:label id=\"lbl" + clmnName + "\" runat=\"server\" CssClass=\"tttable\">" + (desc.Equals("") ? clmnName : desc) + "</asp:label></TD>\r\n";
 templateStr += "           <TD height=\"25\">\r\n";
 if(clmnTypeName.Equals("nvarchar"))
 {
  templateStr += "            <asp:textbox id=\"txt" + clmnName + "\" runat=\"server\" CssClass=\"edline\" Width=\"320px\" MaxLength=\"" + clmnLen + "\"></asp:textbox>\r\n";
 
  //必录项
  if(allowNull.Equals(""))
   templateStr += "            <asp:requiredfieldvalidator id=\"require" + clmnName + "\" runat=\"server\" ControlToValidate=\"txt" + clmnName + "\">*</asp:requiredfieldvalidator>\r\n";
 }
 else if(clmnTypeName.Equals("datetime"))
 {
  templateStr += "            <asp:textbox id=\"txt" + clmnName + "\" runat=\"server\" CssClass=\"edline\" Width=\"320px\" MaxLength=\"10\"></asp:textbox>\r\n";
 
  //必录项
  if(allowNull.Equals(""))
   templateStr += "            <asp:requiredfieldvalidator id=\"require" + clmnName + "\" runat=\"server\" ControlToValidate=\"txt" + clmnName + "\">*</asp:requiredfieldvalidator>\r\n";
  //日期格式校验
  templateStr += "            <asp:RangeValidator id=\"range" + clmnName + "\" runat=\"server\" ErrorMessage=\"请输入合法日期\" Type=\"Date\" MinimumValue=\"1990-1-1\" MaximumValue=\"9999-12-31\" ControlToValidate=\"txt" + clmnName + "\" Display=\"Dynamic\"></asp:RangeValidator>\r\n";
 }

 templateStr += "           </TD>\r\n";
 templateStr += "          </TR>\r\n";
}


补充:
现在我们好多代码都是一个表一个对象的来封装,还包括一些表的关联关系,那么这部分代码是否也能一次生成?这就需要我们来获得表的外键以及依赖关系。

 

获取表的外键:
SELECT     fk.name AS fkname, ftable.name AS tblName, cn.name AS clmn, rtable.name relationTblName, (SELECT     name
                            FROM           syscolumns
                            WHERE       sysforeignkeys.rkeyid =  syscolumns.id AND  sysforeignkeys.rkey =  syscolumns.colid) relationClmn
FROM         sysforeignkeys INNER JOIN
                      sysobjects AS fk ON sysforeignkeys.constid = fk.id INNER JOIN
                      sysobjects AS ftable ON  sysforeignkeys.fkeyid = ftable.id INNER JOIN
                      sysobjects AS rtable ON  sysforeignkeys.rkeyid = rtable.id INNER JOIN
                      syscolumns AS cn ON sysforeignkeys.fkeyid = cn.id AND sysforeignkeys.fkey = cn.colid
where ftable.name='YourTableName'

 

获取表的被依赖关系:
SELECT     fk.name AS fkname, ftable.name AS tblName, cn.name AS clmn, rtable.name relationTblName, (SELECT     name
                            FROM           syscolumns
                            WHERE       sysforeignkeys.rkeyid =  syscolumns.id AND  sysforeignkeys.rkey =  syscolumns.colid) relationClmn
FROM          sysforeignkeys INNER JOIN
                       sysobjects AS fk ON  sysforeignkeys.constid = fk.id INNER JOIN
                       sysobjects AS ftable ON  sysforeignkeys.fkeyid = ftable.id INNER JOIN
                       sysobjects AS rtable ON  sysforeignkeys.rkeyid = rtable.id INNER JOIN
                       syscolumns AS cn ON  sysforeignkeys.fkeyid = cn.id AND  sysforeignkeys.fkey = cn.colid
where rtable.name='YourTableName'


通过这个sql就可以获得表的外键关联表和关联字段,这样和前面我们获得的字段的信息结合起来使用后就可以生成我们所需要的父子表关系了。

 

 

 
上一篇:张朝阳玩弄版权投机,上演贼喊捉贼闹剧
下一篇:用C#实现基于TCP协议的网络通讯
【打印】    【关闭】    【字体变小】    【字体变大】

友情链接

首页  |  建站学院  |  网站建设  |  成功案例  |  业务体系  |  软件定制  |  解决方案  |  联系我们  |  免责声明
中成网建公司地址:四川省成都市双楠双安东巷1号18-3-5 电话:028-6616 5255 版权所有 @ 中成网建
成都网站建设网址:www.csccd.net www.csccd.cn 邮箱:web#csccd.net
信息产业部备案号:蜀ICP备08106559号