大二這年學的的.net,開始一直用三層框架在寫程序,寫那個數據訪問層的時候要寫sql語句,開始因為玩的是小程序,表中的字段不多,但是過后寫的程序比較大一點的時候,表中的字段就多了很多,寫sql都寫死人,而且還容易出錯,想着就來看看能不能自己寫個代碼生成器,上網查找資料,我自己也完成了一代碼生成器,
若文章在表述和代碼方面如有不妥之處,歡迎批評指正。留下你的腳印,歡迎評論!希望能互相學習,
1.首先新建一個SqlHelp類,相信很多人也都是這用實現對數據庫的訪問的吧!!(這個類是和我這個代碼生成器配套使用的,當然你想修改代碼生成器生成的語句你可以下載我的源碼進行修改)
public class SqlHelp { // 在配置文件獲得連接字符串 private static string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; #region 執行sql語句(update,insert,delete)+ExecuteNonQuery(string sql, params SqlParameter[] paras) /// <summary> /// 執行sql語句(update,insert,delete) /// </summary> /// <param name="sql">sql語句</param> /// <param name="paras">可變參數</param> /// <returns>返回影響的行數</returns> public static int ExecuteNonQuery(string sql, params SqlParameter[] paras) { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); using (SqlCommand command = conn.CreateCommand()) { command.CommandText = sql; command.Parameters.AddRange(paras); return command.ExecuteNonQuery(); } } } #endregion #region 執行sql的函數語句(count,sum 等)+ExecuteScalar(string sql, params SqlParameter[] paras) /// <summary> /// 執行sql的函數語句(count,sum 等) /// </summary> /// <param name="sql">sql語句</param> /// <param name="paras">可變參數</param> /// <returns>返回函數值</returns> public static object ExecuteScalar(string sql, params SqlParameter[] paras) { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); using (SqlCommand command = conn.CreateCommand()) { command.CommandText = sql; command.Parameters.AddRange(paras); return command.ExecuteScalar(); } } } #endregion #region 執行sql的select語句+ExecuteTable(string sql, params SqlParameter[] paras) /// <summary> /// 執行sql的select語句 /// </summary> /// <param name="sql">sql語句</param> /// <param name="paras">可變參數</param> /// <returns>返回一張數據表</returns> public static DataTable ExecuteTable(string sql, params SqlParameter[] paras) { using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); using (SqlCommand command = conn.CreateCommand()) { command.CommandText = sql; command.Parameters.AddRange(paras); SqlDataAdapter sda = new SqlDataAdapter(command); DataSet ds = new DataSet(); sda.Fill(ds); return ds.Tables[0]; } } } #endregion /// <summary> /// 數據庫接受的null:當傳入的數據位null時,轉換成DBNull.Value(只有這樣才能插入到數據庫) /// </summary> /// <param name="obj"></param> /// <returns></returns> public static object toDBNull(object obj) { if (obj == null) { return DBNull.Value; } else { return obj; } } /// <summary> /// 把數據庫的null值轉換成程序中null值 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static object toNull(object obj) { if (obj == DBNull.Value) { return null; } else { return obj; } } }
這里我是用wpf來寫的代碼生成器
/// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }
//窗體加載事件
private void Window_Loaded(object sender, RoutedEventArgs e)
{
TablecomboBox.IsEnabled = false;
btnCreateCode.IsEnabled = false;
string path = AppDomain.CurrentDomain.BaseDirectory;
//把每次連接的字符串存儲到1.txt
string Newpath = System.IO.Path.Combine(path, "ConnStr.txt");
txtConnstr.Text = File.ReadAllText(Newpath);
}
//點擊連接按鈕 private void btnConn_Click(object sender, RoutedEventArgs e) { TablecomboBox.IsEnabled = false; btnCreateCode.IsEnabled = false; DataTable datatable; try { //獲得選擇數據庫的所有表名 string sql = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"; datatable = ResultDataTable(sql); } catch (SqlException se) { MessageBox.Show("數據庫連接錯誤!" + se.Message); return; } TablecomboBox.IsEnabled = true; string[] tables = new string[datatable.Rows.Count]; for (int i = 0; i < datatable.Rows.Count; i++) { DataRow row = datatable.Rows[i]; tables[i] = (string)row["TABLE_NAME"]; } //把表名放在下拉框中 TablecomboBox.ItemsSource = tables; TablecomboBox.SelectedIndex = 0; btnCreateCode.IsEnabled = true; string path = AppDomain.CurrentDomain.BaseDirectory; string Newpath = System.IO.Path.Combine(path, "ConnStr.txt");//這樣拼接成的路徑較為安全; File.WriteAllText(Newpath, txtConnstr.Text);//把字符串存到根文件夾下面; } //返回數據庫表
public DataTable ResultDataTable(string sql, params SqlParameter[] parameters)
{
using (SqlConnection connstr = new SqlConnection(txtConnstr.Text))
{
//打開數據庫連接
connstr.Open();
using (SqlCommand command = connstr.CreateCommand())
{
command.CommandText = sql;
command.Parameters.AddRange(parameters);
SqlDataAdapter sda = new SqlDataAdapter(command);
DataSet ds = new DataSet();
//獲取表中的全部信息(如填充每個表中的主鍵和外鍵等)
sda.FillSchema(ds, SchemaType.Source);
sda.Fill(ds);
return ds.Tables[0];
}
}
}
//生成代碼按鈕事件 private void btnCreateCode_Click(object sender, RoutedEventArgs e) { if (TablecomboBox.SelectedIndex <0) { MessageBox.Show("請選擇一個表"); return; } DataColumnCollection columns = Returncolumns(TablecomboBox.SelectedItem.ToString()); //生成實體類 CreateModelCode(columns); //生成數據訪問代碼 CreateDALCode(columns); }
//生成實體類 public void CreateModelCode(DataColumnCollection columns) { StringBuilder sb = new StringBuilder();//用這種方式連接字符串效率更高; sb.Append("public class ").Append(TablecomboBox.SelectedItem).AppendLine("\n{"); foreach (DataColumn column in columns) { sb.Append(" public ").Append(IsNull(column)).Append(" ").Append(column.ColumnName).Append("{set;get;}\n"); } sb.Append("}"); txtModel.Text = sb.ToString(); } public string IsNull(DataColumn column) { //如果列允許為null,並且列在C#中的類型是不可為空的(值類型ValueType) if (column.AllowDBNull&&column.DataType.IsValueType) { return column.DataType + "?"; } else { return column.DataType.ToString(); } }
//生成數據訪問代碼 public void CreateDALCode(DataColumnCollection columns) { ///生成代碼,這里就生成比較常用的幾個方法,你也可以自己添加自己常用的方法 CreateToModel(columns); CreateGetAll(columns); CreateInsert(columns); CreateUpdate(columns); CreateGetById(columns); } #region 生成 把DataRow 轉換成實體類型的方法 /// <summary> /// 生成 把DataRow 轉換成實體類型的方法 /// </summary> /// <param name="columns"></param> public void CreateToModel(DataColumnCollection columns) { StringBuilder sb = new StringBuilder(); sb.Append("public static ").Append(TablecomboBox.SelectedItem).Append(" To").Append(TablecomboBox.SelectedItem); sb.AppendLine("(DataRow row)\n{").Append(" ").Append(TablecomboBox.SelectedItem); sb.Append(" model =new ").AppendLine(TablecomboBox.SelectedItem + "();"); foreach (DataColumn column in columns) { sb.Append(" model.").Append(column.ColumnName).Append("=(").Append(column.DataType); sb.Append(")SqlHelp.toNull(row[\"" + column.ColumnName + "\"]);\n"); } sb.AppendLine(" return model;"); sb.AppendLine("}"); sb.AppendLine(" "); txtDAL.Text += "" + sb.ToString(); } #endregion #region 生成 返回所有數據方法 /// <summary> /// 生成 返回所有數據方法 /// </summary> /// <param name="columns"></param> public void CreateGetAll(DataColumnCollection columns) { StringBuilder sb = new StringBuilder(); sb.Append("public static ").Append(TablecomboBox.SelectedItem).AppendLine("[] GetAll() \n{"); sb.Append(" DataTable datatable= SqlHelp.ExecuteTable(\"select * from ").Append(TablecomboBox.SelectedItem).AppendLine("\");"); sb.Append(" ").Append(TablecomboBox.SelectedItem).Append("[] ").Append("ArrayModel=new "). Append(TablecomboBox.SelectedItem).AppendLine("[datatable.Rows.Count];"); sb.AppendLine(" for (int i=0; i < datatable.Rows.Count; i++)\n {").Append(" ArrayModel[i] =").Append("To") .Append(TablecomboBox.SelectedItem).AppendLine("(datatable.Rows[i]);"); sb.AppendLine(" }").AppendLine(" return ArrayModel;"); sb.AppendLine("}"); sb.AppendLine(" "); txtDAL.Text += sb.ToString(); } #endregion #region 生成數據插入方法 /// <summary> /// 生成數據插入方法 /// </summary> /// <param name="columns"></param> public void CreateInsert(DataColumnCollection columns) { string TableName = TablecomboBox.SelectedItem.ToString(); StringBuilder sb = new StringBuilder(); sb.Append("public static int InsertData(").Append(TableName); sb.AppendLine(" newData)\n{"); sb.Append(" int i=SqlHelp.ExecuteNonQuery(@\"insert ").Append(TableName); sb.Append("("); string columnname = string.Join(",", GetColumnAtName(TableName, false)); sb.Append(columnname).Append(")\n values("); string columnAtname = string.Join(",", GetColumnAtName(TableName, true)); sb.Append(columnAtname); sb.Append(")\",");//values結束; string ParameterStr = string.Join(" ,", ResultParameter(TableName)); sb.Append("\n ").Append(ParameterStr); sb.Append(" );\n").AppendLine(" return i;").AppendLine("}").AppendLine(" ");//Insert語句結束; txtDAL.Text += "" + sb.ToString(); } #endregion #region 生成數據更新方法 /// <summary> /// 生成數據更新方法 /// </summary> /// <param name="columns"></param> public void CreateUpdate(DataColumnCollection columns) { string TableName = TablecomboBox.SelectedItem.ToString(); if (cbPrimaryKey.Items.Count < 1) { MessageBox.Show("不存在主鍵,無法生成UpData代碼和Delete代碼"); return; } StringBuilder sb = new StringBuilder(); sb.Append("public static int UpDate(").Append(TableName); sb.AppendLine(" newData)\n{"); sb.Append(" int i=SqlHelp.ExecuteNonQuery(@\"update ").Append(TableName).Append(" set "); string UpdateStr = string.Join(",", ResultUpdateStr(TableName)); sb.Append("\n ").Append(UpdateStr).Remove(sb.Length - 1, 1).Append(" where ").Append(cbPrimaryKey.SelectedValue).Append("=@").Append(cbPrimaryKey.SelectedValue); sb.Append("\",\n ");//Sql語句結束; string ParameterStr = string.Join(" ,", ResultParameter(TableName)); sb.Append(ParameterStr); sb.AppendLine(" );").AppendLine(" return i;").AppendLine("}").AppendLine(" "); txtDAL.Text += "" + sb.ToString(); //生成刪除方法 CreateDelete(columns); } #endregion #region 生成數據刪除方法 /// <summary> /// 生成數據刪除方法 /// </summary> /// <param name="columns"></param> public void CreateDelete(DataColumnCollection columns) { string TableName = TablecomboBox.SelectedItem.ToString(); StringBuilder sb = new StringBuilder();
//我這里使用的主鍵Guid類型,所以傳遞的Guid類型,當然你修改主鍵類型,你就可以修改下面的字符串Guid為其他類型,后面的CreateGetById也是通過Guid來獲取,若想改變類型自行修改代碼就可以了 sb.Append("public static int DeleteById(Guid id)").AppendLine("{"); sb.Append(" int i = SqlHelp.ExecuteNonQuery(\"delete ").Append(TableName); sb.Append(" where ").Append(cbPrimaryKey.SelectedValue).Append("=@Id\","); sb.AppendLine("\n new SqlParameter(\"@Id\", id));"); sb.Append("\n return i;"); sb.AppendLine("}"); sb.AppendLine(" "); txtDAL.Text += sb.ToString(); } #endregion #region 生成 通過SID獲取實體類的方法+CreateGetById(DataColumnCollection columns) /// <summary> /// 生成 通過SID獲取實體類的方法 /// </summary> /// <param name="columns"></param> public void CreateGetById(DataColumnCollection columns) { string TableName = TablecomboBox.SelectedItem.ToString(); StringBuilder sb = new StringBuilder(); sb.Append("public static ").Append(TableName).Append(" GetById(Guid id)").AppendLine("{"); sb.Append(" DataTable datatable = SqlHelp.ExecuteTable(\"select * from ").Append(TableName); sb.Append(" where ").Append(cbPrimaryKey.SelectedValue).Append("=@Id\","); sb.AppendLine("\n new SqlParameter(\"@Id\", id));").AppendLine(" if(datatable.Rows.Count<0)\n {") .AppendLine(" return null;"); sb.AppendLine(" }").AppendLine(" else if(datatable.Rows.Count==1)\n {").Append(" return To").Append(TableName); sb.AppendLine("(datatable.Rows[0]);").AppendLine(" }").AppendLine(" else\n {").AppendLine(" throw new Exception();"); sb.AppendLine(" }"); sb.AppendLine("}"); sb.AppendLine(" "); txtDAL.Text += sb.ToString(); } #endregion #region 返回數據表的數組列名+ GetColumnAtName(string tablename, bool flag) /// <summary> /// 返回數據表的列名 /// </summary> /// <param name="tablename">數據表名</param> /// <param name="flag">為true時就只返回數據表的列名,為true是在就返回 “@”+數據表列名(為了傳遞可變參數)</param> /// <returns>返回值:把數據表列名按數組返回</returns> public string[] GetColumnAtName(string tablename, bool flag) { DataColumnCollection columns = Returncolumns(tablename); string[] ColumnName = new string[columns.Count]; for (int i = 0; i < columns.Count; i++) { if (flag) { ColumnName[i] = "@" + columns[i].ColumnName; } else { ColumnName[i] = columns[i].ColumnName; } } return ColumnName; } #endregion #region 返回數據表列名+Returncolumns(string tablename) /// <summary> /// 返回數據表列名 /// </summary> /// <param name="tablename">表名</param> /// <returns></returns> public DataColumnCollection Returncolumns(string tablename) { DataTable datatable = ResultDataTable("select top 0 * from " + tablename); DataColumnCollection columns = datatable.Columns; return columns; } #endregion #region 返回數據表可變參數字符串 如:new SqlParameter("@Sid",SqlHelp.toDBNull(Model.Sid))+ ResultParameter(string tablename) /// <summary> /// 返回數據表可變參數字符串 如:new SqlParameter("@Sid",SqlHelp.toDBNull(Model.Sid)) /// </summary> /// <param name="tablename"></param> /// <returns></returns> public string[] ResultParameter(string tablename) { DataColumnCollection columns = Returncolumns(tablename); string[] ParameterStr = new string[columns.Count]; for (int i = 0; i < columns.Count; i++) { ParameterStr[i] = "new SqlParameter(\"@" + columns[i].ColumnName + "\"," + "SqlHelp.toDBNull(newData." + columns[i].ColumnName + "))\n"; } return ParameterStr; } #endregion #region 返回更新字符串+ResultUpdateStr(string tablename) /// <summary> /// 返回更新字符串 /// </summary> /// <param name="tablename"></param> /// <returns></returns> public string[] ResultUpdateStr(string tablename) { DataColumnCollection columns = Returncolumns(tablename); string[] UpdateStr = new string[columns.Count]; for (int i = 0; i < columns.Count; i++) { if (cbPrimaryKey.SelectedValue.ToString() != columns[i].ToString()) { //當檢測到主鍵時;這里返回的更新字符串就不對主鍵進行賦值, //應該在where后面賦值(這里在CreateUpdata(DataColumnCollection columns)方法中生成了主鍵字符串) ; UpdateStr[i] = columns[i].ColumnName + "=@" + columns[i].ColumnName; } } //把主鍵影響UpdateStr數組的Null覆蓋掉; for (int i = 0; i < UpdateStr.Length; i++) { if (UpdateStr[i] == null) { for (int j = i + 1; j < UpdateStr.Length; j++) { UpdateStr[j - 1] = UpdateStr[j]; } } UpdateStr[UpdateStr.Length - 1] = null; } return UpdateStr; } #endregion #region 返回表的主鍵集合 /// <summary> /// 返回表的主鍵集合 /// </summary> /// <param name="tablename"></param> /// <returns></returns> public DataColumn[] GetTablePrimaryKey1(string tablename) { DataTable datatable = ResultDataTable("select top 0 * from " + tablename); DataColumn[] PrimaryKey = datatable.PrimaryKey; if (PrimaryKey.Length <= 0) { return null; } return PrimaryKey; } #endregion #region 表改變時發生事件 /// <summary> /// 表改變時發生事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void TablecomboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { txtModel.Text = " ";//清空實體模型層代碼 txtDAL.Text = "";//清空數據訪問層代碼 DataColumn[] dc = GetTablePrimaryKey1(TablecomboBox.SelectedValue.ToString()); List<string> list = new List<string>(); for (int i = 0; dc != null && i < dc.Length; i++) { list.Add(dc[i].ToString()); } //加載數據表主鍵 cbPrimaryKey.ItemsSource = list; cbPrimaryKey.SelectedIndex = 0; } #endregion }
截圖:
這里是源碼有興趣的可以下載看看http://pan.baidu.com/s/1o6uRVtw