网络上有很多的自动生成代码的工具,有基于模板的像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就可以获得表的外键关联表和关联字段,这样和前面我们获得的字段的信息结合起来使用后就可以生成我们所需要的父子表关系了。
转至http://blog.csdn.net/sunearlier/article/details/2967649