以前很多時候都是使用CodeSmith或動軟生成相關的數據庫訪問代碼(不喜歡使用持久化框架),可以CodeSmith對中文的支持不好,新下載的6.5的版本,怎樣都不能正確顯示中文,動軟代碼生成器的表字段的注釋永遠都顯示不了(李天平的敗筆),有幾個屬性如MySql的smallint,tinyint,得重新更改選項的映射表,太麻煩了。雖然說動軟現在提供了模塊生成功能,批量生成中對表的重命名也不能夠,功能有點弱呀,於是自己寫個代碼生成器,按自己的規則去生成,注釋也出來了,多了注釋提示,對開發幫助很大的。代碼如下:
private void CreateModel() { string connectionString = "server=127.0.0.1;port=3306;User Id=root;Password=root;database=ipbroadcast;Connect Timeout=60;Treat Tiny As Boolean=False"; MySql.Data.MySqlClient.MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connectionString); conn.Open(); DataTable table = conn.GetSchema("TABLES"); foreach (DataRow row in table.Rows) { DataTable sheetTable = GetSchemaTable(conn, row); string tName = row["TABLE_NAME"].ToString(); CreateEntityFile(conn, tName, sheetTable); } conn.Close(); } private DataTable GetSchemaTable(MySqlConnection conn, DataRow row) { string sheetName = row["TABLE_Name"].ToString(); MySqlCommand com = conn.CreateCommand(); com.CommandType = CommandType.Text; com.CommandText = "Select * From " + sheetName; IDataReader reader = com.ExecuteReader(CommandBehavior.SchemaOnly); DataTable table = reader.GetSchemaTable(); com.Dispose(); reader.Close(); return table; } private void CreateEntityFile(MySqlConnection conn, string tName, DataTable table) { //定義生成文件的路徑 string tableName = tName; string schemaName = ""; string colName = ""; string path = @"F:\IPBroadcastModel\Model1"; if (!Directory.Exists(path)) Directory.CreateDirectory(path); MySqlCommand com = conn.CreateCommand(); com.CommandType = CommandType.Text; Dictionary<string, string> dict = new Dictionary<string, string>(); bool isGetComment = false; //寫文件 string clsName = "Ety" + tableName.Substring(3, 1).ToUpper() + tableName.Substring(4); string fileName = clsName + ".cs"; string fullName = Path.Combine(path, fileName); using (FileStream fs = new FileStream(fullName, FileMode.Create)) { StreamWriter sw = new StreamWriter(fs, Encoding.UTF8); sw.WriteLine("using System;"); sw.WriteLine("using System.Text;"); sw.WriteLine("using System.Collections.Generic; "); sw.WriteLine("using System.Data;"); sw.WriteLine("namespace AEBell.DBManager"); sw.WriteLine("{"); sw.WriteLine("\t[Serializable]"); sw.WriteLine("\tpublic class " + clsName); sw.WriteLine("\t{"); foreach (DataRow row in table.Rows) { //tableName = row["BaseTableName"].ToString(); colName = row["ColumnName"].ToString(); schemaName = row["BaseSchemaName"].ToString(); if (!isGetComment) { isGetComment = true; GetFielComment(tableName, schemaName, com, dict); } sw.WriteLine("\t\t/// <summary>"); sw.WriteLine("\t\t/// " + dict[colName]); sw.WriteLine("\t\t/// </summary>"); Type info = row["DataType"] as Type; string declear = info.Name; if (declear.ToUpper() == "SBYTE") //為了適應動軟。 declear = "Byte"; bool isNull = (bool)row["AllowDBNull"]; if (isNull && info.BaseType.Name == "ValueType") declear += "?"; sw.WriteLine("\t\tpublic " + declear + " " + colName.Substring(0, 1).ToUpper() + colName.Substring(1)); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\tget;"); sw.WriteLine("\t\t\tset;"); sw.WriteLine("\t\t}"); } sw.WriteLine("\t}"); sw.WriteLine("}"); sw.Close(); } } private static void GetFielComment(string tableName, string schemaName, MySqlCommand com, Dictionary<string, string> dict) { string comment = ""; com.CommandText = "Select COLUMN_NAME,DATA_TYPE, COLUMN_COMMENT From INFORMATION_SCHEMA.COLUMNS where table_name ='" + tableName + "' AND table_schema = '" + schemaName + "'"; // AND column_name LIKE '" + colName + "'"; IDataReader reader = com.ExecuteReader(); while (reader.Read()) { string colName = reader.GetString(0); comment = reader.GetString(2); dict[colName] = comment; } reader.Close(); }
雖然實現不是很嚴謹,DAL和BLL層也沒有實現,但有需要之人是可以很快實現的。不對之處,請指正。