自己寫的C#三層代碼生成器


  • 思來想去用T4生成代碼要學習它的語法,C#本身能很簡單地生成txt文件,為啥不直接批量替換模板方式自己寫個的三層代碼生成器。說干就干,2個小時搞定。當然各層還可以做的更精細,比如DAL層Add方法Insert、Update語句中主鍵就不該出現等。但是大體上是能使用了。另外,生成的代碼格式有些地方不規整,但是編譯不出錯,我們可以在實現具體類時借助vs格式化功能(快捷鍵ctrl+E+D)來使其規整或調模板。
  • 生成類文件整體思路:定模板,設置替換點,取得數據庫中所有表及字段,遍歷替換,輸出cs文件。類文件模板是根據自己項目代碼實踐而定。
  • 具體算法:
    1、讀取數據庫中所有表及字段,返回DBInfo(Dictionary<{表,說明},Dictionary<{字段,說明},數據類型>>)
    2、遍歷DBInfo,生成Model層代碼
    3、遍歷DBInfo,生成DAL層代碼
    4、遍歷DBInfo,生成BLL層代碼
  • 代碼說明:我是在現有舊項目中建的一個test.aspx中實現的,其中DbHelperSQL是數據庫幫助類(網上可以隨意找到),運行本代碼前最好是先搭建的解決方案能訪問DB了,再運行本代碼,因為代碼要連接項目DB,獲得所有表及其字段以便批量生產三層文件。代碼中用到的三層模板是我根據Dapper使用經驗而確定的,大家可以替換成自己的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Text;
using System.IO;

public partial class test : System.Web.UI.Page
{
   /***
	* ○ 生成類文件整體思路:定模板,設置替換點,遍歷DBInfo替換,輸出cs文件。類文件模板是根據自己項目代碼實踐而定。
	* ○ 具體算法:
	*     1、讀取數據庫中所有表及字段,返回DBInfo(Dictionary<{表,說明},Dictionary<{字段,說明},數據類型>>)
	*     2、遍歷DBInfo,生成Model層代碼
	*     3、遍歷DBInfo,生成DAL層代碼
	*     4、遍歷DBInfo,生成BLL層代碼
	***/
    protected void Page_Load(object sender, EventArgs e)
    {
        Dictionary<string, Dictionary<string, string>> r = GetDBInfo();
        ModelFactory(r);
        DALFactory(r);
        BLLFactory(r);
        Response.Write(r.Count);
    }
    #region 生成三層代碼

    #region 全局變量
    static string DalNameSpace = "CMS.DAL";//DAL層命名空間(下同)
    static string ModelNameSpace = "CMS.Model";
    static string BllNameSpace = "CMS.BLL";
    static string DalLayerPath = @"d:\Test\DAL\";//dal層代碼生成代碼文件存放路徑(下同)
    static string ModelLayerPath = @"d:\Test\Model\";
    static string BllLayerPath = @"d:\Test\BLL\";
    static char DicSplit = '≡';//分隔符,注意:代碼不是因此出錯,建議不要修改 
    #endregion

    #region 得到數據庫中所有表及字段

    private static Dictionary<string, Dictionary<string, string>> GetDBInfo()
    {
        //Dictionary<{表,說明},Dictionary<{字段,說明},數據類型>>
        Dictionary<string, Dictionary<string, string>> dicR = new Dictionary<string, Dictionary<string, string>>();
        string getTables = " SELECT name FROM sysobjects  WHERE xtype = 'U' ";

        DataTable dt = DbHelperSQL.Query(getTables).Tables[0];
        foreach (DataRow item in dt.Rows)
        {
            string tblName = item[0].ToString();
            //"SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + tblName+"' ";
            string getTblFields = @"SELECT 
                    表名       = case when a.colorder=1 then d.name else '' end,
                    表說明     = case when a.colorder=1 then isnull(f.value,'') else '' end,
                    字段序號   = a.colorder,
                    字段名     = a.name,
                    標識       = case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else '' end,
                    主鍵       = case when exists(SELECT 1 FROM sysobjects where xtype='PK' and parent_obj=a.id and name in (
                                     SELECT name FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid))) then '√' else '' end,
                    類型       = b.name,
                    占用字節數 = a.length,
                    長度       = COLUMNPROPERTY(a.id,a.name,'PRECISION'),
                    小數位數   = isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0),
                    允許空     = case when a.isnullable=1 then '√'else '' end,
                    默認值     = isnull(e.text,''),
                    字段說明   = isnull(g.[value],'')
                FROM 
                    syscolumns a
                left join 
                    systypes b 
                on 
                    a.xusertype=b.xusertype
                inner join 
                    sysobjects d 
                on 
                    a.id=d.id  and d.xtype='U' and  d.name<>'dtproperties'
                left join 
                    syscomments e 
                on 
                    a.cdefault=e.id
                left join 
                sys.extended_properties   g 
                on 
                    a.id=G.major_id and a.colid=g.minor_id  
                left join
                sys.extended_properties f
                on 
                    d.id=f.major_id and f.minor_id=0
                where   d.name='" + tblName + "'   order by  a.id,a.colorder";
            DataTable dtTbl = DbHelperSQL.Query(getTblFields).Tables[0];
            Dictionary<string, string> dicItem = new Dictionary<string, string>();
            foreach (DataRow tbl in dtTbl.Rows)
            {
                if (tbl[1].ToString() != "")
                    tblName += DicSplit + tbl[1].ToString();
                string COLUMN_NAME = tbl[3].ToString() + DicSplit + tbl[12].ToString();
                string DATA_TYPE = tbl[6].ToString();
                dicItem.Add(COLUMN_NAME, DATA_TYPE);
            }
            dicR.Add(tblName, dicItem);
        }
        return dicR;
    }
    #endregion

    #region 遍歷生成Model層代碼
    private static void ModelFactory(Dictionary<string, Dictionary<string, string>> dic)
    {
        foreach (var item in dic)
        {
            #region 類模板
            StringBuilder sb = new StringBuilder();
            sb.Append("  using System;                                        \r\n");
            sb.Append("  using System.Text;                                   \r\n");
            sb.Append("                                                       \r\n");
            sb.Append("  /**************************************************  \r\n");
            sb.Append("   * 類 名 稱 :  【類名稱】                            \r\n");
            sb.Append("   * 版 本 號 :  v1.0.0.0                              \r\n");
            sb.Append("   * 說    明 :  【表職責】                            \r\n");
            sb.Append("   * 作    者 :                                        \r\n");
            sb.Append("   * 創建時間 : 【時間戳】                                \r\n");
            sb.Append("  **************************************************/  \r\n");
            sb.Append("  namespace 【命名空間】                                  \r\n");
            sb.Append("  {                                                    \r\n");
            sb.Append("      public class 【表】                               \r\n ");
            sb.Append("      {                                                \r\n");
            sb.Append("                                                       \r\n");
            sb.Append("          public 【表】()                              \r\n");
            sb.Append("          {                                           \r\n ");
            sb.Append("          }                                           \r\n ");
            sb.Append("         【屬性部分】                                  \r\n ");
            sb.Append("  	}                                                \r\n ");
            sb.Append("  }                                                   \r\n ");

            #endregion

            #region 屬性部分
            StringBuilder propPart = new StringBuilder();
            foreach (var field in item.Value)
            {
                string[] key = field.Key.Split(DicSplit);
                string type = ChangeToCSharpType(field.Value.ToString());//Dictionary<{表,說明},Dictionary<{字段,說明},數據類型>>
                string fName = key[0];
                string fRemark = key.Length == 2 ? key[1] : "";
                string first = field.Key.Substring(0, 1);//第一個字母
                fName = fName.Substring(1, fName.Length - 1);//不含第一個字母
                string _f = first.ToLower() + fName;
                string pF = first.ToUpper() + fName;
                propPart.Append("                                                  \r\n");
                propPart.AppendFormat("    private {0} {1};                          \r\n", type, _f);
                propPart.AppendFormat("    //{0}                                       \r\n", fRemark);
                propPart.AppendFormat("    public {0} {1}                              \r\n", type, pF);
                propPart.Append("          {                                            \r\n");
                propPart.Append("              get { return " + _f + "; }                     \r\n");
                propPart.Append("              set { " + _f + " = value; }                    \r\n");
                propPart.Append("          }                                            \r\n");
            } 
            #endregion

            string[] tableInfo = item.Key.Split(DicSplit);
            string tblName = tableInfo[0];
            string tblWork = tableInfo.Length == 2 ? tableInfo[1] : "";
            string r = sb.ToString()
                    .Replace("【類名稱】", tblName + "表實體類")
                    .Replace("【時間戳】", DateTime.Now.ToString())
                    .Replace("【命名空間】", ModelNameSpace)
                    .Replace("【表】", tblName)
                    .Replace("【表職責】", tblWork)
                    .Replace("【屬性部分】", propPart.ToString());
            CreateTxt(ModelLayerPath + tblName + "Model.cs", ModelLayerPath, r);
        }

    }
    #endregion

    #region 遍歷生成DAL層代碼
    private static void DALFactory(Dictionary<string, Dictionary<string, string>> dic)
    {

        foreach (var item in dic)
        {
            StringBuilder sb = new StringBuilder();
            #region 類模板
            sb.Append("using System.Collections.Generic;                                             \r\n");
            sb.Append("using System.Text;                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("/**************************************************                           \r\n  ");
            sb.Append(" * 類 名 稱 :  【類名稱】                                                      \r\n  ");
            sb.Append(" * 版 本 號 :  v1.0.0.0                                                       \r\n  ");
            sb.Append(" * 說    明 :  用於【表】數據持久化                                            \r\n ");
            sb.Append(" * 作    者 :                                                                 \r\n  ");
            sb.Append(" * 創建時間 :  【時間戳】                                                      \r\n");
            sb.Append("****************************************************/                         \r\n  ");
            sb.Append("namespace 【命名空間】                                                            \r\n  ");
            sb.Append("{                                                                             \r\n  ");
            sb.Append("    public class 【表】DAL                                                    \r\n  ");
            sb.Append("    {                                                                         \r\n  ");
            sb.Append("        #region select                                                        \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        public List<【表】> Select(【表】 model)                               \r\n ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            string sql = \"SELECT * FROM 【表】 where \";                     \r\n   ");
            sb.Append("            return DapperHelper.Select<【表】>(sql, model);                   \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region delete                                                        \r\n  ");
            sb.Append("        public bool Delete(【表】 model)                                      \r\n  ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            string sql = \"DELETE FROM 【表】 WHERE Id=@Id\";                 \r\n");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql, model) > 0;              \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region insert                                                        \r\n  ");
            sb.Append("        public bool Add(【表】 model)                                         \r\n  ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("			   【當前表Insert】                                                  \r\n  ");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql.ToString(), model) > 0;   \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region update                                                        \r\n  ");
            sb.Append("        public bool Update(【表】 model)                                      \r\n ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            【當前表Update】               \r\n  ");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql, model) > 0;              \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("    }                                                                         \r\n  ");
            sb.Append("}                                                                             \r\n  ");
            #endregion
            string tblName = item.Key.Split(DicSplit)[0];
            string insetSQL = GetInsertSQL(tblName, item.Value);
            string updateSQL = GetUpdateSQL(tblName, item.Value);
            string r = sb.ToString()
                        .Replace("【類名稱】", tblName + "表DAL類")
                        .Replace("【時間戳】", DateTime.Now.ToString())
                        .Replace("【命名空間】", DalNameSpace)
                        .Replace("【表】", tblName)
                        .Replace("【當前表Insert】", insetSQL)
                        .Replace("【當前表Update】", updateSQL);
            CreateTxt(DalLayerPath + tblName + "DAL.cs", DalLayerPath, r);
        }

    }
    #endregion

    #region 遍歷生成BLL層代碼
    private static void BLLFactory(Dictionary<string, Dictionary<string, string>> dic)
    {

        foreach (var item in dic)
        {
            StringBuilder sb = new StringBuilder();
            #region 類模板
            sb.Append("using System;                                                                 \r\n");
            sb.Append("using System.Collections.Generic;                                             \r\n");
            sb.Append("using System.Linq;                                                            \r\n");
            sb.Append("using System.Text;                                                            \r\n");
            sb.Append("using System.Threading.Tasks;                                                 \r\n");
            sb.Append("                                                                              \r\n  ");
            sb.Append("/**************************************************                           \r\n  ");
            sb.Append(" * 類 名 稱 :  【類名稱】                                                      \r\n  ");
            sb.Append(" * 版 本 號 :  v1.0.0.0                                                       \r\n  ");
            sb.Append(" * 說    明 :  用於【表】表業務操作                                            \r\n ");
            sb.Append(" * 作    者 :                                                                 \r\n  ");
            sb.Append(" * 創建時間 :  【時間戳】                                                      \r\n");
            sb.Append("****************************************************/                         \r\n  ");
            sb.Append("namespace 【命名空間】                                                            \r\n  ");
            sb.Append("{                                                                             \r\n  ");
            sb.Append("    public class 【表】BLL                                                    \r\n  ");
            sb.Append("    {                                                                         \r\n  ");
            sb.Append("        #region select                                                        \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        public List<【表】> Select(【表】 model, string sqlWhere)             \r\n ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            return 【表】DAL.Select(model, sqlWhere);                  \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region delete                                                        \r\n  ");
            sb.Append("        public bool Delete(【表】 model)                                      \r\n  ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            return 【表】DAL.Delete(model);                                   \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region insert                                                        \r\n  ");
            sb.Append("        public bool Add(【表】 model)                                         \r\n  ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            return 【表】DAL.Add(model);                                     \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("                                                                              \r\n  ");
            sb.Append("        #region update                                                        \r\n  ");
            sb.Append("        public bool Update(【表】 model)                                      \r\n ");
            sb.Append("        {                                                                     \r\n  ");
            sb.Append("            return 【表】DAL.Update(model);                                    \r\n  ");
            sb.Append("        }                                                                     \r\n  ");
            sb.Append("        #endregion                                                            \r\n  ");
            sb.Append("    }                                                                         \r\n  ");
            sb.Append("}                                                                             \r\n  ");
            #endregion
            string tblName = item.Key.Split(DicSplit)[0];
            string r = sb.ToString()
                        .Replace("【類名稱】", tblName + "表BLL類")
                        .Replace("【時間戳】", DateTime.Now.ToString())
                        .Replace("【命名空間】", BllNameSpace)
                        .Replace("【表】", tblName);
            CreateTxt(BllLayerPath + tblName + "BLL.cs", BllLayerPath, r);
        }

    }
    #endregion 

    #region 其他
    
    //為某個表生成insert語句
    public static string GetInsertSQL(string tableName, Dictionary<string, string> filedDic)
    {
        StringBuilder sb = new StringBuilder();

        sb.AppendFormat("StringBuilder sql = new StringBuilder();           \r\n");
        sb.AppendFormat(" #region sql                                       \r\n");
        sb.AppendFormat(" sql.Append(\"INSERT INTO {0}  \");                \r\n", tableName);
        sb.AppendFormat(" sql.Append(\" ( \"); \r\n");
        int i = 0;
        foreach (var item in filedDic)
        {
            string[] key = item.Key.Split(DicSplit);
            string filedName = key[0];
            string splitChar = ",";
            if (i + 1 == filedDic.Count)
                splitChar = "";
            sb.AppendFormat(" sql.Append(\"   {0} {1} \");                  \r\n", filedName, splitChar);
            i++;
        }
        sb.AppendFormat(" sql.Append(\" ) \");                              \r\n");
        sb.AppendFormat(" sql.Append(\" VALUES  ( \");                      \r\n");
        int b = 0;
        foreach (var item in filedDic)
        {
            string[] key = item.Key.Split(DicSplit);
            string filedName = key[0];
            string splitChar = ",";
            if (b + 1 == filedDic.Count)
                splitChar = "";
            sb.AppendFormat(" sql.Append(\"     @{0} {1} \");               \r\n", filedName, splitChar);
            b++;
        }
        sb.AppendFormat(" sql.Append(\" ) \");                             \r\n");
        sb.AppendFormat(" #endregion sql                                   \r\n");
        return sb.ToString();
    }
    
    //為某個表生成update語句
    public static string GetUpdateSQL(string tableName, Dictionary<string, string> filedDic)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("StringBuilder sql = new StringBuilder();           \r\n");
        sb.AppendFormat(" #region sql                                       \r\n");
        sb.AppendFormat(" sql.Append(\" Update {0} set   \");               \r\n", tableName);
        int i = 0;
        foreach (var item in filedDic)
        {
            string[] key = item.Key.Split(DicSplit);
            string filedName = key[0];
            string splitChar = ",";
            if (i + 1 == filedDic.Count)
                splitChar = "";
            sb.AppendFormat(" sql.Append(\"   {0}=@{0} {1} \"); \r\n", filedName, splitChar);
            i++;
        }
        sb.AppendFormat(" sql.Append(\" Where Id=@Id   \"); \r\n");
        sb.AppendFormat(" #endregion sql                                       \r\n");
        return sb.ToString();
    }

    //生成cs文件
    public static void CreateTxt(string filePath, string folderPath, string fileContent)
    {
        if (!Directory.Exists(folderPath))//如果不存在就創建文件夾
            Directory.CreateDirectory(folderPath);
        FileStream fs = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None);
        StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
        sw.Write(fileContent);
        sw.Close();
        fs.Close();
    }

    // 數據庫中與C#中的數據類型對照
    private static string ChangeToCSharpType(string type)
    {
        string reval = string.Empty;
        switch (type.ToLower())
        {
            case "int":
                reval = "int";
                break;
            case "text":
                reval = "string";
                break;
            case "bigint":
                reval = "int";
                break;
            case "binary":
                reval = "byte[]";
                break;
            case "bit":
                reval = "bool";
                break;
            case "char":
                reval = "string";
                break;
            case "datetime":
                reval = "DateTime";
                break;
            case "decimal":
                reval = "decimal";
                break;
            case "float":
                reval = "double";
                break;
            case "image":
                reval = "byte[]";
                break;
            case "money":
                reval = "decimal";
                break;
            case "nchar":
                reval = "string";
                break;
            case "ntext":
                reval = "string";
                break;
            case "numeric":
                reval = "decimal";
                break;
            case "nvarchar":
                reval = "string";
                break;
            case "real":
                reval = "single";
                break;
            case "smalldatetime":
                reval = "DateTime";
                break;
            case "smallint":
                reval = "int";
                break;
            case "smallmoney":
                reval = "decimal";
                break;
            case "timestamp":
                reval = "DateTime";
                break;
            case "tinyint":
                reval = "byte";
                break;
            case "uniqueidentifier":
                reval = "System.Guid";
                break;
            case "varbinary":
                reval = "byte[]";
                break;
            case "varchar":
                reval = "string";
                break;
            case "Variant":
                reval = "Object";
                break;
            default:
                reval = "string";
                break;
        }
        return reval;
    }
    #endregion

    #endregion
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM