最近工作电脑装完win10后,之前使用的codeSmith安装不了,索性自己写一个。
界面比较简单,如下图:
第一行为Oracle数据库的连接字符串。连接成功后,填充表到第4行的下拉列表中。
第二行为实体类命名空间。
第三行为保存生成类、xml文件选择文件夹。
1 private void btnConnect_Click(object sender, RoutedEventArgs e) 2 { 3 try 4 { 5 using (OracleConnection conn = new OracleConnection()) 6 { 7 conn.ConnectionString = txtConnStr.Text; 8 9 using (OracleCommand cmd = conn.CreateCommand()) 10 { 11 cmd.CommandText = "select distinct table_name from user_tables order by table_name"; 12 13 DataTable dt = new DataTable(); 14 15 OracleDataAdapter adapter = new OracleDataAdapter(); 16 adapter.SelectCommand = cmd; 17 18 adapter.Fill(dt); 19 20 cbTables.DisplayMemberPath = "TABLE_NAME"; 21 cbTables.SelectedValuePath = "TABLE_NAME"; 22 cbTables.ItemsSource = dt.DefaultView; 23 24 } 25 26 MessageBoxShow("连接成功!"); 27 28 } 29 } 30 catch 31 { 32 MessageBoxShow("连接失败!"); 33 } 34 }
1 private void btnChoseDirectory_Click(object sender, RoutedEventArgs e) 2 { 3 FolderBrowserDialog folderDialog = new FolderBrowserDialog(); 4 DialogResult dialogResult = folderDialog.ShowDialog(); 5 6 if (dialogResult == System.Windows.Forms.DialogResult.OK) 7 { 8 labDirectoryPath.Content = folderDialog.SelectedPath.Trim(); 9 } 10 }
1 private void btnSave_Click(object sender, RoutedEventArgs e) 2 { 3 if (string.IsNullOrEmpty(txtEntityClassNamespace.Text.Trim())) 4 { 5 MessageBoxShow("请输入实体命名空间名称!"); 6 txtEntityClassNamespace.Focus(); 7 return; 8 } 9 if (labDirectoryPath.Content == null) 10 { 11 MessageBoxShow("请选择文件夹保存生成文件!"); 12 btnChoseDirectory.Focus(); 13 return; 14 } 15 if (cbTables.SelectedValue == null) 16 { 17 MessageBoxShow("请选择表名!"); 18 return; 19 } 20 21 DataTable dt = GetTableSchemaByTableName(); 22 23 GenerateClass(dt); 24 25 GenerateMappingXml(dt); 26 27 MessageBoxShow("生成成功!"); 28 } 29 30 private string OracleTypeToCSType(string oracleType) 31 { 32 string csType = string.Empty; 33 34 switch (oracleType.ToUpper()) 35 { 36 case "NVARCHAR2": 37 case "VARCHAR2": 38 case "CHAR": 39 csType = "string"; 40 break; 41 case "LONG": 42 csType = "long"; 43 break; 44 case "NUMBER": 45 csType = "int"; 46 break; 47 case "DATE": 48 csType = "datetime"; 49 break; 50 } 51 52 return csType; 53 } 54 55 private DataTable GetTableSchemaByTableName() 56 { 57 string selectSQL = @"select t1.COLUMN_NAME,t1.data_type,t1.data_length,t1.nullable,t2.comments, 58 replace(initcap(t1.TABLE_NAME),'_','') className 59 from user_tab_columns t1 left 60 join user_col_comments t2 61 on t1.TABLE_NAME = t2.table_name and t1.COLUMN_NAME = t2.column_name 62 where t1.table_name = :table_name 63 order by to_number(t1.column_id)"; 64 65 DataTable dt = new DataTable(); 66 using (OracleConnection conn = new OracleConnection()) 67 { 68 conn.ConnectionString = txtConnStr.Text; 69 70 using (OracleCommand cmd = conn.CreateCommand()) 71 { 72 cmd.CommandText = selectSQL; 73 cmd.Parameters.Add(new OracleParameter(":table_name", cbTables.SelectedValue)); 74 75 OracleDataAdapter adapter = new OracleDataAdapter(); 76 adapter.SelectCommand = cmd; 77 78 adapter.Fill(dt); 79 } 80 } 81 82 return dt; 83 } 84 85 private void GenerateClass(DataTable dt) 86 { 87 string entityClassNamespace = txtEntityClassNamespace.Text; 88 if (dt.Rows.Count > 0) 89 { 90 string className = dt.Rows[0]["className"].ToString(); 91 92 using (FileStream csStream = new FileStream(System.IO.Path.Combine(labDirectoryPath.Content.ToString(), className + ".cs"), FileMode.Create, FileAccess.Write)) 93 { 94 using (StreamWriter writer = new StreamWriter(csStream, Encoding.Default)) 95 { 96 writer.WriteLine(string.Format("namespace {0}", entityClassNamespace)); 97 98 writer.WriteLine("{"); 99 writer.WriteLine(string.Format(@" public class {0} : BaseModel 100 {{", className)); 101 for (int i = 0; i < dt.Rows.Count; i++) 102 { 103 writer.WriteLine(string.Format(@" /// <summary> 104 /// {0} 105 /// </summary>", dt.Rows[i]["comments"].ToString())); 106 writer.WriteLine(string.Format(" public virtual {0} {1} {{ set; get; }}", 107 OracleTypeToCSType(dt.Rows[i]["data_type"].ToString()), 108 dt.Rows[i]["COLUMN_NAME"].ToString())); 109 writer.WriteLine(); 110 } 111 writer.WriteLine(" }"); 112 writer.WriteLine("}"); 113 } 114 } 115 116 } 117 } 118 119 private void GenerateMappingXml(DataTable dt) 120 { 121 string entityClassNamespace = txtEntityClassNamespace.Text; 122 if (dt.Rows.Count > 0) 123 { 124 string className = dt.Rows[0]["className"].ToString(); 125 126 XNamespace xmlns = "urn:nhibernate-mapping-2.2"; 127 128 var xDoc = new XDocument(new XElement(xmlns + "hibernate-mapping", 129 new XElement(xmlns + "class", 130 new XAttribute("name", string.Format("{0}.{1},{0}", entityClassNamespace, className)), 131 new XAttribute("table", cbTables.SelectedValue), 132 new XAttribute("lazy", "true"), 133 new XElement(xmlns + "id", 134 new XAttribute("column", "ID"), 135 new XAttribute("name", "ID"), 136 new XElement(xmlns + "generator", 137 new XAttribute("class", "sequence"), 138 new XElement(xmlns + "param", 139 new XAttribute("name", "sequence"), 140 new XText(string.Format("SEQ_{0}", cbTables.SelectedValue)) 141 )))))); 142 143 XElement _class = xDoc.Root.Element(xmlns + "class"); 144 145 for (int i = 0; i < dt.Rows.Count; i++) 146 { 147 string columnName = dt.Rows[i]["COLUMN_NAME"].ToString(); 148 149 XElement property = new XElement(xmlns + "property"); 150 property.SetAttributeValue("name", columnName); 151 property.SetAttributeValue("column", columnName); 152 153 _class.Add(property); 154 } 155 156 xDoc.Save(System.IO.Path.Combine(labDirectoryPath.Content.ToString(), className + ".hbm.xml")); 157 } 158 }
总结:
- 使用user_tables系统表查询用户所有表
- 使用user_tab_columns查询表的所有列
- 使用user_col_comments查询表的备注信息
- 使用文件流生成实体类,使用Linq to xml生成*.hbm.xml文件