分享

自动代码生成器

 quasiceo 2013-03-04

自动代码生成器

重复的数据库操作,无休止的写存储过程参数列表,不停的对数据库的内容进行映射,无聊而且又容易出错,你是否已经厌倦了这样写代码。

其实这些代码的格式都几乎是固定的,完全可以自动生成。

我最近写了这么个小东东,希望能给大家一点帮助

思路路下

用OleDbConnection的GetOleDbSchemaTable方法获取数据库的机构存放在自己定义的对象中。

    //根据数据库获得数据库映射。
        public Schema GetSchema()
        
{
            Schema schema
=new Schema();
            
int i=0;
            con.Open();
            DataTable schemaTable 
= con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[] {nullnullnull"TABLE"});
            
foreach (DataRow dr in  schemaTable.Rows)
            
{
                
//表名
                schema.Tables.Add(new SchemaTable(dr["TABLE_NAME"].ToString()));
                
//字段名
                DataTable columnTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
                    
new object[] {nullnull, ((SchemaTable)schema.Tables[i]).TableName,null});
                
foreach(DataRow dr2 in columnTable.Rows)
                
{
                    
int j=0;
                    SchemaColumn col
=new SchemaColumn(dr2["COLUMN_NAME"].ToString(),((OleDbType)dr2["DATA_TYPE"]));
                    
if (dr2["CHARACTER_MAXIMUM_LENGTH"]!=DBNull.Value)
                    
{
                        col.ColumnSize
=Convert.ToInt32(dr2["CHARACTER_MAXIMUM_LENGTH"]);
                    }

                    col.IsNullAble
=(bool)dr2["IS_NULLABLE"];
    
                    ((SchemaTable)schema.Tables[i]).Columns.Add(col);
                    j
++;
                }

                i
++;
            }

            DataTable pkTable
=con.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, null);
            
foreach (DataRow dr in pkTable.Rows)
            
{
                
for (int x=0;x<schema.Tables.Count;x++)
                
{
                    
if (schema.Tables[x].TableName==dr["TABLE_NAME"].ToString())
                    
{
                        
for(int y=0;y<schema.Tables[x].Columns.Count;y++)
                        
{
                            
if (schema.Tables[x].Columns[y].ColumnName==dr["COLUMN_NAME"].ToString())
                            
{
                                schema.Tables[x].Columns[y].IsPK
=true;
                                
break;
                            }

                        }

                        
break;
                    }

                }

            }


            con.Close();
            
return schema;    
        }

可能有人会问为什么使用OleDbConnection的GetOleDbSchemaTable方法,而不使用select * from sysobjects查询对象,我在这里考虑的是可以支持多种数据库平台,因为GetOleDbSchemaTable可以获得多种数据库的结构可以说是 一劳永益,但这样做也会带来问题,因为得到的结构会使用同意的OleDbType来表示,在使用时必须转换到对应的SqlDBType和 OracleDbType等,转换时类型可能不正确,在这里可以做了一些限制来保证转换的正确,

    case OleDbType.WChar:
                
{
                    
if (size<50)
                    
{
                        
return "SqlDbType.NChar";
                    }

                    
else if (size<1000)
                    
{
                        
return "SqlDbType.NVarChar";
                    }

                    
else
                    
{
                        
return "SqlDbType.NText";
                    }

                }

例如SqlServer数据库中的NChar,NVarchar和NText都被映射成OleDbType.WChar,所以我做出三个字段大小的一个限制来确保映射的正确性。

用类似如下代码生成相应的代码

        public override string BuildInsertFun(SchemaTable table) 
        

            StringBuilder sb 
= new StringBuilder() ; 
            sb.Append(
"public bool Add() ") ; 
            sb.Append(
"{ ") ; 
            sb.Append(
" ") ; 
            
string strInsert = ""insert into " + table.TableName + "("
            
string strFiledList = "" ; 
            
string strParamList = "" ; 
            
for(int i=0;i<table.Columns.Count;i++)
            
{
                
string strName = table.Columns[i].ColumnName ; 
                strFiledList 
= strFiledList + strName + "" ; 
                strParamList 
= strParamList + "@" + strName + "" ; 
            }

            strFiledList 
= strFiledList.Trim().TrimEnd(',') ; 
            strParamList 
= strParamList.Trim().TrimEnd(',') ; 
            sb.Append(
" string strSql = " + strInsert + strFiledList+ ")" ") ; 
            sb.Append(
" +"values(" + strParamList+ ")" ; ") ; 
            sb.Append(
" ") ; 
            sb.Append(
" SqlCommand command = new SqlCommand(strSql,conn) ; ") ; 
            sb.Append(
" ") ; 
            sb.Append(helper.BuildParameterString(table,
false,true));

            sb.Append(helper.AddCatchString()) ; 
   
            sb.Append(
"} ") ; 
            
return sb.ToString(); 
        }
 

这是一段生成的代码

using System;
using System.Data;
using System.Data.SqlClient;

namespace 命名空间
{
    
/// </summary>
    
///注释
    
/// </summary>

    public class AdminDB
    
{
        
private SqlConnection conn=new SqlConnection();
        
private SqlCommand command=new SqlCommand();
        
public AdminDB()
        
{
            conn.ConnectionString
=ConStrLib.GetConStr();
        }

        
private string adminID ;
        
public string AdminID 
        
{
            
get
            
{
                
return adminID ;
            }

            
set
            
{
                adminID 
= value ;
            }

        }

        
        
        
private string passWord ;
        
public string PassWord 
        
{
            
get
            
{
                
return passWord ;
            }

            
set
            
{
                passWord 
= value ;
            }

        }

        
        
        
public bool Add()
        
{
        
            
string strSql = "insert into Admin(AdminID, PassWord)"
                
+"values(@AdminID, @PassWord)" ;
        
            SqlCommand command 
= new SqlCommand(strSql,conn) ;
        
            command.Parameters.Add(
"@AdminID",SqlDbType.Char) ;
            command.Parameters[
"@AdminID"].Value = AdminID ;
        
            command.Parameters.Add(
"@PassWord",SqlDbType.Char) ;
            command.Parameters[
"@PassWord"].Value = PassWord ;
        
            
try
            
{
                conn.Open() ;
                command.ExecuteNonQuery() ;
                
return true ;
            }

            
catch(Exception e)
            
{
                
throw(new Exception("Error in the Database"+e.Message)) ;
            }

            
finally
            
{
                conn.Close() ;
            }

        }

        
public bool Modify()
        
{
            
string strSql ="update Admin set AdminID = @AdminID, PassWord = @PassWord "
                
+ " where AdminID=@AdminID";
        
            SqlCommand command 
= new SqlCommand(strSql,conn) ;
        
            command.Parameters.Add(
"@AdminID",SqlDbType.Char) ;
            command.Parameters[
"@AdminID"].Value = AdminID ;
        
            command.Parameters.Add(
"@PassWord",SqlDbType.Char) ;
            command.Parameters[
"@PassWord"].Value = PassWord ;
        
            
try
            
{
                conn.Open() ;
                command.ExecuteNonQuery() ;
                
return true ;
            }

            
catch(Exception e)
            
{
                
throw(new Exception("Error in the Database"+e.Message)) ;
            }

            
finally
            
{
                conn.Close() ;
            }

        }

        
public bool Delete()
        
{
            
string strSql ="delete from Admin"
                
+ " where AdminID=@AdminID";
        
            SqlCommand command 
= new SqlCommand(strSql,conn) ;
        
            command.Parameters.Add(
"@AdminID",SqlDbType.Char) ;
            command.Parameters[
"@AdminID"].Value = AdminID ;
        
            
try
            
{
                conn.Open() ;
                command.ExecuteNonQuery() ;
                
return true ;
            }

            
catch(Exception e)
            
{
                
throw(new Exception("Error in the Database"+e.Message)) ;
            }

            
finally
            
{
                conn.Close() ;
            }

        }

        
public DataSet GetAll()
        
{
            
string strSql ="select * from Admin";
            SqlDataAdapter da 
= new SqlDataAdapter(strSql,conn) ;
            DataSet ds 
= new DataSet() ;
        
            
try
            
{
                da.Fill(ds) ;
            }

            
catch(Exception e)
            
{
                
throw(new Exception("Error in the Database"+e.Message)) ;
            }

            
finally
            
{
                da.Dispose() ;
            }

            
return ds ;
        }

        
public DataSet GetById()
        
{
            
string strSql ="select * from Admin"
                
+ " where AdminID=@AdminID";
        
            SqlDataAdapter da 
= new SqlDataAdapter(strSql,conn) ;
            DataSet ds 
= new DataSet() ;
        
            da.SelectCommand.Parameters.Add(
"@AdminID",SqlDbType.Char) ;
            da.SelectCommand.Parameters[
"@AdminID"].Value = AdminID ;
        
            
try
            
{
                da.Fill(ds) ;
            }

            
catch(Exception e)
            
{
                
throw(new Exception("Error in the Database"+e.Message)) ;
            }

            
finally
            
{
                da.Dispose() ;
            }

            
return ds ;
        }

    }

}

通过修改代码可以生成不同格式(包括数据操作或映射),不同语言,支持多种数据库的代码。

在支持多数据库时,我使用了工厂,通过不同的连接字符串创建不同的对象。

public CodeMakerFactory CreateCodeMakerFactory(string conStr,CodeLanguageType lanType)
        
{
            conStr
=conStr.ToUpper();
            
//Sql
            if (conStr.IndexOf("SQLOLEDB",0,conStr.Length-1)>0)
            
{
                
switch (lanType)
                
{
                    
case CodeLanguageType.CSharp:
                    
{
                        
return new CSharpSQLMakerFactory();
                    }

                    
default:
                    
{
                        
throw new CodeMakerException("还没做!");
                    }

                }

            }

            
//Oracle
            else if(conStr.IndexOf("MSDAORA",0,conStr.Length-1)>0)
            
{
                
throw new CodeMakerException("还没做!");
            }

            
else
            
{
                
throw new CodeMakerException("不支持的数据库类型!");
            }

        }

 


博主上一篇:《.NET中统一的存储过程调用方法(收藏) 》的具体实现
博主下一篇:关于能自定义格式的、支持多语言的、支持多数据库的代码生成器的想法
首页上一篇:弥补Reflector反编译对中文支持的不足
首页下一篇:开始研究Constructor().

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多