日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单代码生成器原理剖析(一)

發布時間:2023/12/2 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单代码生成器原理剖析(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上篇文章(深入淺出三層架構)分析了簡單三層架構的實現。包括Model,DAL(數據訪問層),BLL(業務邏輯層)的實現。

實際開發中,由于重復代碼的操作,會花費大量時間,如果以代碼生成器來自動生成三層架構代碼,即節省精力,又可以節省大量的時間來做其他業務邏輯的代碼,提高開發效率。

常用的代碼生成器有:動軟,CodeSmith 等。

簡單代碼生成器的基本功能描述:

一鍵生成Model,DAL,BLL,包括對應數據庫中表的Model的自動生成,包括生成屬性、添加、修改、刪除、查詢。

界面展示:

生成器開發技術要點:

  • 查詢系統視圖:INFORMATION_SCHEMA.TABLES、?INFORMATION_SCHEMA.COLUMNS? 可以獲得數據庫中表、列的相關信息。
  • 字符串的拼接:StringBuilder的使用,其AppendLine()會自動換行。
  • 將字符串寫入文本文件:File.WriteAllText()
  • 為了降低開發難度,先假設條件多一些,如表的主鍵都為Id,且自動增長,之后再逐步完善
  • 關鍵代碼:

    ?

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;
    using System.IO;

    namespace CodeGenerator
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }
    /// <summary>
    /// 執行ExecuteDataTable(),得到DataTable
    /// </summary>
    /// <param name="cmdText"></param>
    /// <param name="parameters"></param>
    /// <returns></returns>
    public DataTable ExecuteDataTable(string cmdText,
    params SqlParameter[] parameters)
    {
    using (SqlConnection conn=new SqlConnection(txtConnStr.Text))
    {
    conn.Open();
    using(SqlCommand cmd=conn.CreateCommand())
    {
    cmd.CommandText = cmdText;
    cmd.Parameters.AddRange(parameters);
    using (SqlDataAdapter adapter=new SqlDataAdapter (cmd))
    {
    DataTable dt = new DataTable();
    adapter.Fill(dt);
    return dt;
    }
    }
    }

    }

    private void Form1_Load(object sender, EventArgs e)
    {
    txtConnStr.Text = @"Data Source=EYES\SQLEXPRESS;Initial Catalog=SanCeng;Integrated Security=True";
    }

    private void btnConnStr_Click(object sender, EventArgs e)
    {

    //清空
    clbTables.Items.Clear();
    //查詢系統試圖
    string sql = "select * from INFORMATION_SCHEMA.TABLES";
    DataTable dt = ExecuteDataTable(sql);
    //根據系統視圖取得TABLE_NAME
    foreach (DataRow row in dt.Rows)
    {
    string tablename = Convert.ToString(row["TABLE_NAME"]);
    clbTables.Items.Add(tablename);
    }

    }

    private void btnGo_Click(object sender, EventArgs e)
    {
    //連接字符串
    //方法AppendLine()追加字符串且自動執行換行

    foreach (string tableName in clbTables.CheckedItems)
    {
    string sql = "select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@TABLE_NAME ";
    DataTable dt = ExecuteDataTable(sql,new SqlParameter("TABLE_NAME",tableName));

    #region 生成Model
    CreatModel(tableName, dt);
    #endregion

    #region 生成DAL


    CreatDAL(tableName, dt);
    #endregion
    #region 生成BLL
    CreatBLL(tableName, dt);
    #endregion
    }
    }

    private static void CreatDAL(string tableName, DataTable dt)
    {
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("using System;");
    sb.AppendLine("using System.Collections.Generic;");
    sb.AppendLine("using System.Linq;");
    sb.AppendLine("using System.Text;");
    sb.AppendLine("using 三層架構Demo.Model;");
    sb.AppendLine("using System.Data.SqlClient;");
    sb.AppendLine("using System.Data;");
    sb.AppendLine("namespace 三層架構Demo.DAL");
    sb.AppendLine("{");
    sb.AppendLine("class " + tableName + "DAL");
    sb.AppendLine("{");
    //去掉Id
    sb.AppendLine(" public int Addnew(" + tableName + " model)");
    sb.AppendLine("{");
    List<String> cols = new List<string>();
    List<String> parameters = new List<string>();
    foreach (DataRow row in dt.Rows)
    {
    string col = Convert.ToString(row["COLUMN_NAME"]);
    string parameter = "";
    if (col.ToLower()!="id")
    {
    parameter= "@" + Convert.ToString(row["COLUMN_NAME"]);
    cols.Add(col);
    parameters.Add(parameter);
    }
    //parameters.Add(parameter)放外面加上一個NULL,所以會多出一個逗號
    // parameters.Add(parameter);

    }

    sb.AppendLine("string sql = \"insert into " + tableName + "(" + String.Join(",", cols) + ") output inserted.Id values(" + String.Join(",", parameters) + ")\";");
    sb.AppendLine("object obj= SQLHelper.ExecuteScalar(sql");

    foreach (DataRow row in dt.Rows)
    {
    string col = Convert.ToString(row["COLUMN_NAME"]);
    if (col.ToLower() != "id")
    {
    sb.AppendLine(",new SqlParameter(\"" + col + "\",model." + col + ")");
    }

    }
    sb.AppendLine(");");
    sb.AppendLine("return Convert.ToInt32(obj);");
    sb.AppendLine("}");
    //Delete方法

    sb.AppendLine(" public int Delete(int id)");
    sb.AppendLine("{");
    sb.AppendLine(" string sql = \"delete from " + tableName + " where Id=@Id\";");
    sb.AppendLine("return SQLHelper.ExecuteNonQuery(sql,new SqlParameter(\"Id\",id));");
    sb.AppendLine("}");

    //Update方法
    sb.AppendLine("public int Update("+tableName+" model)");
    sb.AppendLine("{");
    string[] uParams1=(from col in cols select col+"=@"+col).ToArray();

    sb.AppendLine(" string sql = \"update "+tableName+" set "+String.Join(",",uParams1)+" where Id=@Id\";");

    string[] uParams2 = (from col in cols select "new SqlParameter(\"" + col + "\",model." + col + ")").ToArray();
    sb.AppendLine(" return SQLHelper.ExecuteNonQuery(sql, " + String.Join(",", uParams2) + " ,new SqlParameter(\"Id\",model.Id));");
    sb.AppendLine("}");

    //GetId方法
    sb.AppendLine(" public "+tableName+" Get(int id)");
    sb.AppendLine("{");
    sb.AppendLine("string sql=\"select * from "+tableName+" where Id=@Id\";");
    sb.AppendLine(" DataTable dt=SQLHelper.ExecuteDataTable(sql,new SqlParameter(\"Id\",id));");
    sb.AppendLine("if (dt.Rows.Count<=0)");
    sb.AppendLine("{");
    sb.AppendLine(" return null;");
    sb.AppendLine("}");
    sb.AppendLine(" else if (dt.Rows.Count==1)");
    sb.AppendLine("{");
    sb.AppendLine(""+tableName+" model1 = new "+tableName+"();");
    foreach (DataRow row in dt.Rows)
    {
    string col = Convert.ToString(row["COLUMN_NAME"]);
    string dataType = Convert.ToString(row["data_TYPe"]);
    sb.AppendLine("model1." + col + " = Convert." + Get(GetType(dataType).ToString()) + "(dt.Rows[0][\"" + col + "\"]);");

    }
    sb.AppendLine("return model1;");
    sb.AppendLine("}");
    sb.AppendLine("else");
    sb.AppendLine("{");
    sb.AppendLine(" throw new Exception(\"數據庫中有兩條及以上重復數據\");");
    sb.AppendLine("}");
    sb.AppendLine("}");

    //IEnumerable()方法
    sb.AppendLine(" public IEnumerable<"+tableName+"> GetAll()");
    sb.AppendLine("{");
    sb.AppendLine(" string sql = \"select * from "+tableName+"\";");
    sb.AppendLine("DataTable dt = SQLHelper.ExecuteDataTable(sql);");
    sb.AppendLine(" List<"+tableName+"> list = new List<"+tableName+">();");
    sb.AppendLine(" foreach (DataRow row in dt.Rows)");
    sb.AppendLine("{");
    sb.AppendLine("" + tableName + " model = new " + tableName + "();");
    foreach (DataRow row in dt.Rows)
    {
    string col = Convert.ToString(row["COLUMN_NAME"]);
    string dataType = Convert.ToString(row["data_TYPE"]);
    sb.AppendLine("model." + col + " = Convert." + Get(GetType(dataType).ToString()) + "(row[\"" + col + "\"]);");

    }
    sb.AppendLine(" list.Add(model);");
    sb.AppendLine("}");
    sb.AppendLine("return list;");
    sb.AppendLine("}");
    sb.AppendLine("}");
    sb.AppendLine("}");
    File.WriteAllText(@"d:\"+tableName+"DAL.cs",sb.ToString());


    }
    /// <summary>
    /// 數據庫類型轉換為C#類型
    /// </summary>
    /// <param name="dataType"></param>
    /// <returns></returns>
    private static Type GetType(string dataType)
    {
    switch (dataType.ToLower())
    {
    case "nvarchar":
    case "varchar":
    case "nchar":
    case "char":
    return typeof(string);
    case "int" :
    return typeof(int);
    case "bigint":
    return typeof(long);
    case "bit":
    return typeof(bool);
    case "datetime":
    return typeof(DateTime);
    default:
    return typeof(object);
    }

    }

    private static string Get(string dataType)
    {

    switch (dataType.ToLower())
    {
    case "system.string":
    return "ToString";
    case "system.int32":
    return "ToInt32";
    case "system.int64":
    return "ToInt64";
    case "system.datetime":
    return "ToDateTime";
    case "system.boolean":
    return "ToBoolean";

    default:
    throw new Exception("找不到匹配的數據類型");

    }
    }
    private static void CreatModel(string tableName, DataTable dt)
    {
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("using System;");
    sb.AppendLine("using System.Collections.Generic;");
    sb.AppendLine("using System.Linq;");
    sb.AppendLine("using System.Text;");
    sb.AppendLine("namespace 三層架構Demo.Model");
    sb.AppendLine("{");
    sb.AppendLine("");
    sb.AppendLine("class " + tableName);
    sb.AppendLine("{");

    foreach (DataRow row in dt.Rows)
    {
    string dataType = Convert.ToString(row["DATA_TYPE"]);

    string columnName = Convert.ToString(row["COLUMN_NAME"]);

    sb.AppendLine("public " + GetType(dataType) + " " + columnName + " { get;set;}");
    }
    sb.AppendLine("}");
    sb.AppendLine("}");
    File.WriteAllText(@"d:\" + tableName + ".cs", sb.ToString());
    //MessageBox.Show(sb.ToString());

    }

    private static void CreatBLL(string tableName, DataTable dt)
    {
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("using System;");
    sb.AppendLine("using System.Collections.Generic;");
    sb.AppendLine("using System.Linq;");
    sb.AppendLine("using System.Text;");
    sb.AppendLine("using 三層架構Demo.Model;");
    sb.AppendLine("using 三層架構Demo.DAL;");
    sb.AppendLine("using System.Data.SqlClient;");
    sb.AppendLine("using System.Data;");
    sb.AppendLine("namespace 三層架構Demo.BLL");
    sb.AppendLine("{");
    sb.AppendLine("class " + tableName+"BLL");
    sb.AppendLine("{");
    sb.AppendLine("public int Addnew("+tableName+" model)");
    sb.AppendLine("{");
    sb.AppendLine(" return new "+tableName+"DAL().Addnew(model);");
    sb.AppendLine("}");
    sb.AppendLine(" public int Delete(int id)");
    sb.AppendLine("{");
    sb.AppendLine(" return new "+tableName+"DAL().Delete(id);");
    sb.AppendLine("}");
    sb.AppendLine(" public int Update("+tableName+" model)");
    sb.AppendLine("{");
    sb.AppendLine(" return new " + tableName + "DAL().Update(model);");
    sb.AppendLine("}");
    sb.AppendLine(" public "+tableName+" Get(int id)");
    sb.AppendLine("{");
    sb.AppendLine(" return new "+tableName+"DAL().Get(id);");
    sb.AppendLine("}");
    sb.AppendLine(" public IEnumerable<"+tableName+"> GetAll()");
    sb.AppendLine("{");
    sb.AppendLine(" return new "+tableName+"DAL().GetAll();");
    sb.AppendLine("}");
    sb.AppendLine("}");
    sb.AppendLine("}");
    File.WriteAllText(@"d:\" + tableName + "BLL.cs", sb.ToString());
    }
    }
    }



    總結:
    忽略了很多限制因素,所以代碼生成器功能不是很完善。隨著要考慮的條件增多,代碼生成器越加復雜。但萬變不離其中,只要有耐心,繼續AppendLine()添加新語句,相信功能會愈加完善。“
    工欲善其事必先利其器“,程序員不僅會用代碼生成器,而且知道其原理才是優秀的程序員。切勿”知其然而不知其所以然“。


    ?

    ?

    ?

    ?

    ?

    ?

    轉載于:https://www.cnblogs.com/OceanEyes/archive/2012/02/16/CodeGenerator.html

    總結

    以上是生活随笔為你收集整理的简单代码生成器原理剖析(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。