開發小工具的原因:1、我們公司的開發是客戶端用C#,服務端用Java,前後臺在通訊交互的時候,會用到Oracle資料庫的欄位,因為伺服器端有公司總經理開發的一個根據Oracle資料庫的表生成的class文件,每次都是等服務端都寫好了實體類以後,我們再複製、粘貼,修改欄位的類型為string,因為在生...
開發小工具的原因:
1、我們公司的開發是客戶端用C#,服務端用Java,前後臺在通訊交互的時候,會用到Oracle資料庫的欄位,因為伺服器端有公司總經理開發的一個根據Oracle資料庫的表生成的class文件,每次都是等服務端都寫好了實體類以後,我們再複製、粘貼,修改欄位的類型為string,因為在生成的時候,是根據Oracle資料庫里的欄位類型生成的java文件,但是我們在前後臺通信的時候,為了不失精度的一些問題,一般都用string類型來傳遞,因此每次修改都比較費事。
2、VS2015在封裝欄位的時候,不會像2012一樣,在欄位的下方,而是統一的封裝到一起,即欄位都在上方,屬性統一的在下方。
小工具界面效果:
這個是剛打開小工具的頁面,連接按鈕上面的幾個Textbox就是連接資料庫時需要的參數。
連接成功以後,把上面的連接部分隱藏掉,為了能有一個稍微大一點的空間,左側用的是TreeView,父節點是表的Owner,子節點是表
點擊左側TreeView的父節點,則其擁有的表全部顯示在右側
點擊左側的子節點,則顯示出來,這個表具體有哪些欄位,要生成的VO里的欄位就是指這些欄位。
NameSpace是指要生成的文件的命名空間,如果不輸入,則預設Test,點擊生成VO,則會同時生成兩個文件,在不同的文件夾下,一個帶通知機制,一個不帶通知機制,需要哪個是根據實際情況來定。
開發過程:
1、要連接資料庫,則自然要有連接資料庫的實體類
public class ConnVo : ObjectNotifyPropertyChanged { private string connIP;//ip地址 private string connPort;//埠 private string connSid;//伺服器名稱 private string connUser;//用戶名 private string connPwd;//密碼 public string ConnIP { get { return connIP; } set { connIP = value; RaisePropertyChanged("ConnIP"); } } public string ConnPort { get { return connPort; } set { connPort = value; RaisePropertyChanged("ConnPort"); } } public string ConnSid { get { return connSid; } set { connSid = value; RaisePropertyChanged("ConnSid"); } } public string ConnUser { get { return connUser; } set { connUser = value; RaisePropertyChanged("ConnUser"); } } public string ConnPwd { get { return connPwd; } set { connPwd = value; RaisePropertyChanged("ConnPwd"); } } }ConnVo
2、因為是對Oracle進行操作,因此資料庫連接、Select語句神馬的肯定少不了,因此專門有一個資料庫操作類
public class DBHelper { /// <summary> /// 聲明連接 /// </summary> protected static OracleConnection Connection; /// <summary> /// 返回Connection /// </summary> /// <param name="ip">地址</param> /// <param name="port">埠</param> /// <param name="sid">服務名稱</param> /// <param name="user">用戶</param> /// <param name="pwd">密碼</param> /// <returns>OleDbConnection</returns> private static OracleConnection ConnForOracle(string ip, string port, string sid, string user, string pwd) { string connStr; connStr = "Data Source=(DESCRIPTION = (ADDRESS_LIST= (ADDRESS = (PROTOCOL = TCP)(HOST = " + ip + ")(PORT = " + port + "))) (CONNECT_DATA = (SERVICE_NAME = " + sid + ")));User ID=" + user + ";Password=" + pwd + ";"; Connection = new OracleConnection(connStr); return Connection; } /// <summary> /// 連接資料庫 /// </summary> /// <param name="ip">地址</param> /// <param name="port">埠</param> /// <param name="sid">服務名稱</param> /// <param name="user">用戶</param> /// <param name="pwd">密碼</param> public static bool OpenConnection(string ip, string port, string sid, string user, string pwd) { ConnForOracle(ip, port, sid, user, pwd); try { //不為空 並且 是關閉或者斷了的情況下,才連接 if (Connection != null && (Connection.State == System.Data.ConnectionState.Closed || Connection.State == System.Data.ConnectionState.Broken)) { Connection.Open(); ReturnOwner = Select("SELECT OWNER, TABLE_NAME FROM ALL_TAB_COMMENTS ORDER BY OWNER, TABLE_NAME"); } MessageBox.Show(Connection.State.ToString()); return true; } catch (Exception ex) { MessageBox.Show(ex.Message.ToString()); return false; } } /// <summary> /// 關閉 /// </summary> public static void CloseConnection() { //不為空 並且 是打開狀態下才關閉 if (Connection != null && Connection.State == System.Data.ConnectionState.Open) { Connection.Close(); } } /// <summary> /// 查詢 /// </summary> /// <param name="sql">SQL語句</param> /// <returns></returns> private static DataTable Select(string sql) { OracleCommand cmd = new OracleCommand(sql, Connection); OracleDataAdapter oda = new OracleDataAdapter(cmd); DataTable dt = new DataTable(); oda.Fill(dt); cmd.Dispose(); return dt; } /// <summary> /// 獲取表名 /// </summary> /// <param name="owner">擁有者</param> public static void GetTableName(string owner) { ReturnTableName = Select("SELECT OWNER, TABLE_NAME, TABLE_TYPE, COMMENTS FROM ALL_TAB_COMMENTS WHERE OWNER='" + owner + "' ORDER BY OWNER, TABLE_TYPE, TABLE_NAME"); } /// <summary> /// 獲取表內容 /// </summary> /// <param name="owner">擁有者</param> /// <param name="name">表名</param> public static void GetTableContent(string owner, string name) { ReturnTableContent = Select("SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_LENGTH,(SELECT COMMENTS FROM ALL_COL_COMMENTS WHERE TABLE_NAME = '" + name + "' AND OWNER = '" + owner + "' AND COLUMN_NAME = a.COLUMN_NAME)COMMENTS FROM ALL_TAB_COLUMNS a WHERE TABLE_NAME = '" + name + "' AND OWNER = '" + owner + "' ORDER BY NULLABLE, COLUMN_NAME "); } #region 欄位 /// <summary> /// 要返回擁有者 /// </summary> private static DataTable returnOwner; public static DataTable ReturnOwner { get { return returnOwner; } set { returnOwner = value; } } /// <summary> /// 返回表名 /// </summary> private static DataTable returnTableName; public static DataTable ReturnTableName { get { return returnTableName; } set { returnTableName = value; } } /// <summary> /// 返回表內容 /// </summary> private static DataTable returnTableContent; public static DataTable ReturnTableContent { get { return returnTableContent; } set { returnTableContent = value; } } #endregion }DBHelper
3、為了方便顯示,要寫一個Oracle的實體類,就是DataGrid顯示的內容
public class TableVo : ObjectNotifyPropertyChanged { private string schema;//圖表 private string name;//名稱 private string comments;//註解 private string type;//類型 private string nullable;//是否可空 private string dataLength;//欄位長度 public string Schema { get { return schema; } set { schema = value; RaisePropertyChanged("Schema"); } } public string Name { get { return name; } set { name = value; RaisePropertyChanged("Name"); } } public string Comments { get { return comments; } set { comments = value; RaisePropertyChanged("Comments"); } } public string Type { get { return type; } set { type = value; RaisePropertyChanged("Type"); } } public string Nullable { get { return nullable; } set { nullable = value; RaisePropertyChanged("Nullable"); } } public string DataLength { get { return dataLength; } set { dataLength = value; RaisePropertyChanged("DataLength"); } } }TableVo
4、由於小工具的左側是一個TreeView,因此有一個TreeView實體,更便於管理和修改,而且此實體中一定要有父節點和子節點,已方便區分,和後期開發
public class PropertyNodeItem:ObjectNotifyPropertyChanged { private string icon; private string parentName; private string childrenName; private bool isExpanded; private List<PropertyNodeItem> children; public string Icon { get { return icon; } set { icon = value; RaisePropertyChanged("Icon"); } } public string ParentName { get { return parentName; } set { parentName = value; RaisePropertyChanged("ParentName"); } } public string ChildrenName { get { return childrenName; } set { childrenName = value; RaisePropertyChanged("ChildrenName"); } } public bool IsExpanded { get { return isExpanded; } set { isExpanded = value; RaisePropertyChanged("IsExpanded"); } } public List<PropertyNodeItem> Children { get { return children; } set { children = value; RaisePropertyChanged("Children"); } } public PropertyNodeItem() { Children = new List<PropertyNodeItem>(); } }PropertyNodeItem
5、創建CS文件,需要同時創建兩個,一個帶有通知機制,一個不帶有通知機制,創建方法無外乎就是拼接String,然後寫入文件,很簡單,就是在寫的過程中,註意一下格式和轉義字元
public class CreateVo { //不含通知機制 private static string pathVo1 = @"Dis/VoWithoutNotify"; //包含通知機制 private static string pathVo2 = @"Dis/VoWithNotify"; /// <summary> /// 判斷是否存在文件夾,不存在則創建 /// </summary> /// <returns></returns> public static bool CreateDirectory() { if (!Directory.Exists(pathVo1)) { Directory.CreateDirectory(pathVo1); } if (!Directory.Exists(pathVo2)) { Directory.CreateDirectory(pathVo2); } if (Directory.Exists(pathVo1) && Directory.Exists(pathVo2)) return true; else return false; } /// <summary> /// 生成不含通知機制的VO /// </summary> /// <param name="NameSpace">命名空間</param> /// <param name="name">文件名</param> /// <param name="listName">列表</param> public static void CreateVoNoINotifyPropertyChanged(string NameSpace,string name,List<TableVo> listName) { FileStream fs = new FileStream(pathVo1 + "/" + name + ".cs", FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.Write(CreateCSNoINotifyPropertyChanged(NameSpace,name,listName)); sw.Flush(); sw.Close(); fs.Close(); } /// <summary> /// 生成包含通知機制的VO /// </summary> /// <param name="NameSpace">命名空間</param> /// <param name="name">文件名</param> /// <param name="listName">列表</param> public static void CreateVoWithINotifyPropertyChanged(string NameSpace, string name, List<TableVo> listName) { FileStream fs = new FileStream(pathVo2 + "/" + name + ".cs", FileMode.Create); StreamWriter sw = new StreamWriter(fs); sw.Write(CreateCSWithINotifyPropertyChanged(NameSpace, name, listName)); sw.Flush(); sw.Close(); fs.Close(); } /// <summary> /// 創建不含通知機制的CS文件 /// </summary> /// <param name="NameSpace">命名空間</param> /// <param name="name">文件名</param> /// <param name="listName">列表</param> /// <returns></returns> private static string CreateCSNoINotifyPropertyChanged(string NameSpace,string name,List<TableVo> listName) { string content = ""; content += "using System;\r\n"; content += "using System.Collections.Generic;\r\n"; content += "using System.Linq;\r\n"; content += "using System.Text;\r\n"; content += "\r\n"; content += "namespace " + "" + NameSpace + "" + "\r\n"; content += "{\r\n"; content += " public class " + "" + name + "" + "\r\n"; content += " {\r\n"; foreach(TableVo s in listName) { content += " private string " + s.Name.ToLower() + ";" + "\r\n"; content += " /// <summary>\r\n"; content += " /// " + s.Comments + "\r\n"; content += " /// </summary>\r\n"; content += " public string " + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length-1).ToLower() + "\r\n"; content += " {\r\n"; content += " get\r\n"; content += " {\r\n"; content += " return " + s.Name.ToLower() + ";\r\n"; content += " }\r\n"; content += "\r\n"; content += " set\r\n"; content += " {\r\n"; content += " " + s.Name.ToLower() + " = value;\r\n"; content += " }\r\n"; content += " }\r\n"; content += "\r\n"; } content += " }\r\n"; content += "}\r\n"; return content; } /// <summary> /// 創建包含通知機制的CS文件 /// </summary> /// <param name="NameSpace">命名空間</param> /// <param name="name">文件名</param> /// <param name="listName">列表</param> /// <returns></returns> private static string CreateCSWithINotifyPropertyChanged(string NameSpace, string name, List<TableVo> listName) { string content = ""; content += "using System;\r\n"; content += "using System.Collections.Generic;\r\n"; content += "using System.Linq;\r\n"; content += "using System.Text;\r\n"; content += "using System.ComponentModel;\r\n"; content += "\r\n"; content += "namespace " + "" + NameSpace + "" + "\r\n"; content += "{\r\n"; content += " public class " + "" + name + "" + ":INotifyPropertyChanged" + "\r\n"; content += " {\r\n"; content += " public event PropertyChangedEventHandler PropertyChanged;\r\n"; content += " public void RaisePropertyChanged(string propertyName)\r\n"; content += " {\r\n"; content += " if (PropertyChanged != null)\r\n"; content += " {\r\n"; content += " PropertyChanged(this, new PropertyChangedEventArgs(propertyName));\r\n"; content += " }\r\n"; content += " }\r\n"; content += "\r\n"; foreach (TableVo s in listName) { content += " private string " + s.Name.ToLower() + ";" + "\r\n"; content += " /// <summary>\r\n"; content += " /// " + s.Comments + "\r\n"; content += " /// </summary>\r\n"; content += " public string " + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length - 1).ToLower() + "\r\n"; content += " {\r\n"; content += " get\r\n"; content += " {\r\n"; content += " return " + s.Name.ToLower() + ";\r\n"; content += " }\r\n"; content += "\r\n"; content += " set\r\n"; content += " {\r\n"; content += " " + s.Name.ToLower() + " = value;\r\n"; content += " RaisePropertyChanged(\"" + s.Name.Substring(0, 1) + s.Name.Substring(1, s.Name.Length - 1).ToLower() + "\");\r\n"; content += " }\r\n"; content += " }\r\n"; content += "\r\n"