自动代码生成器重复的数据库操作,无休止的写存储过程参数列表,不停的对数据库的内容进行映射,无聊而且又容易出错,你是否已经厌倦了这样写代码。 其实这些代码的格式都几乎是固定的,完全可以自动生成。 我最近写了这么个小东东,希望能给大家一点帮助 思路路下 用OleDbConnection的GetOleDbSchemaTable方法获取数据库的机构存放在自己定义的对象中。 //根据数据库获得数据库映射。
public Schema GetSchema() { Schema schema=new Schema(); int i=0; con.Open(); DataTable schemaTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,new object[] {null, null, null, "TABLE"}); foreach (DataRow dr in schemaTable.Rows) { //表名 schema.Tables.Add(new SchemaTable(dr["TABLE_NAME"].ToString())); //字段名 DataTable columnTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] {null, null, ((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("不支持的数据库类型!"); } }
博主下一篇:关于能自定义格式的、支持多语言的、支持多数据库的代码生成器的想法 首页上一篇:弥补Reflector反编译对中文支持的不足 首页下一篇:开始研究Constructor(). |
|