自己写的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:TestDAL";//dal层代码生成代码文件存放路径(下同)
    static string ModelLayerPath = @"d:TestModel";
    static string BllLayerPath = @"d:TestBLL";
    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;                                        
");
            sb.Append("  using System.Text;                                   
");
            sb.Append("                                                       
");
            sb.Append("  /**************************************************  
");
            sb.Append("   * 类 名 称 :  【类名称】                            
");
            sb.Append("   * 版 本 号 :  v1.0.0.0                              
");
            sb.Append("   * 说    明 :  【表职责】                            
");
            sb.Append("   * 作    者 :                                        
");
            sb.Append("   * 创建时间 : 【时间戳】                                
");
            sb.Append("  **************************************************/  
");
            sb.Append("  namespace 【命名空间】                                  
");
            sb.Append("  {                                                    
");
            sb.Append("      public class 【表】                               
 ");
            sb.Append("      {                                                
");
            sb.Append("                                                       
");
            sb.Append("          public 【表】()                              
");
            sb.Append("          {                                           
 ");
            sb.Append("          }                                           
 ");
            sb.Append("         【属性部分】                                  
 ");
            sb.Append("  	}                                                
 ");
            sb.Append("  }                                                   
 ");

            #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("                                                  
");
                propPart.AppendFormat("    private {0} {1};                          
", type, _f);
                propPart.AppendFormat("    //{0}                                       
", fRemark);
                propPart.AppendFormat("    public {0} {1}                              
", type, pF);
                propPart.Append("          {                                            
");
                propPart.Append("              get { return " + _f + "; }                     
");
                propPart.Append("              set { " + _f + " = value; }                    
");
                propPart.Append("          }                                            
");
            } 
            #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;                                             
");
            sb.Append("using System.Text;                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("/**************************************************                           
  ");
            sb.Append(" * 类 名 称 :  【类名称】                                                      
  ");
            sb.Append(" * 版 本 号 :  v1.0.0.0                                                       
  ");
            sb.Append(" * 说    明 :  用于【表】数据持久化                                            
 ");
            sb.Append(" * 作    者 :                                                                 
  ");
            sb.Append(" * 创建时间 :  【时间戳】                                                      
");
            sb.Append("****************************************************/                         
  ");
            sb.Append("namespace 【命名空间】                                                            
  ");
            sb.Append("{                                                                             
  ");
            sb.Append("    public class 【表】DAL                                                    
  ");
            sb.Append("    {                                                                         
  ");
            sb.Append("        #region select                                                        
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        public List<【表】> Select(【表】 model)                               
 ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            string sql = "SELECT * FROM 【表】 where ";                     
   ");
            sb.Append("            return DapperHelper.Select<【表】>(sql, model);                   
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region delete                                                        
  ");
            sb.Append("        public bool Delete(【表】 model)                                      
  ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            string sql = "DELETE FROM 【表】 WHERE Id=@Id";                 
");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql, model) > 0;              
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region insert                                                        
  ");
            sb.Append("        public bool Add(【表】 model)                                         
  ");
            sb.Append("        {                                                                     
  ");
            sb.Append("			   【当前表Insert】                                                  
  ");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql.ToString(), model) > 0;   
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region update                                                        
  ");
            sb.Append("        public bool Update(【表】 model)                                      
 ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            【当前表Update】               
  ");
            sb.Append("            return DapperHelper.NoQuery<【表】>(sql, model) > 0;              
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("    }                                                                         
  ");
            sb.Append("}                                                                             
  ");
            #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;                                                                 
");
            sb.Append("using System.Collections.Generic;                                             
");
            sb.Append("using System.Linq;                                                            
");
            sb.Append("using System.Text;                                                            
");
            sb.Append("using System.Threading.Tasks;                                                 
");
            sb.Append("                                                                              
  ");
            sb.Append("/**************************************************                           
  ");
            sb.Append(" * 类 名 称 :  【类名称】                                                      
  ");
            sb.Append(" * 版 本 号 :  v1.0.0.0                                                       
  ");
            sb.Append(" * 说    明 :  用于【表】表业务操作                                            
 ");
            sb.Append(" * 作    者 :                                                                 
  ");
            sb.Append(" * 创建时间 :  【时间戳】                                                      
");
            sb.Append("****************************************************/                         
  ");
            sb.Append("namespace 【命名空间】                                                            
  ");
            sb.Append("{                                                                             
  ");
            sb.Append("    public class 【表】BLL                                                    
  ");
            sb.Append("    {                                                                         
  ");
            sb.Append("        #region select                                                        
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        public List<【表】> Select(【表】 model, string sqlWhere)             
 ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            return 【表】DAL.Select(model, sqlWhere);                  
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region delete                                                        
  ");
            sb.Append("        public bool Delete(【表】 model)                                      
  ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            return 【表】DAL.Delete(model);                                   
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region insert                                                        
  ");
            sb.Append("        public bool Add(【表】 model)                                         
  ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            return 【表】DAL.Add(model);                                     
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("                                                                              
  ");
            sb.Append("        #region update                                                        
  ");
            sb.Append("        public bool Update(【表】 model)                                      
 ");
            sb.Append("        {                                                                     
  ");
            sb.Append("            return 【表】DAL.Update(model);                                    
  ");
            sb.Append("        }                                                                     
  ");
            sb.Append("        #endregion                                                            
  ");
            sb.Append("    }                                                                         
  ");
            sb.Append("}                                                                             
  ");
            #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();           
");
        sb.AppendFormat(" #region sql                                       
");
        sb.AppendFormat(" sql.Append("INSERT INTO {0}  ");                
", tableName);
        sb.AppendFormat(" sql.Append(" ( "); 
");
        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} ");                  
", filedName, splitChar);
            i++;
        }
        sb.AppendFormat(" sql.Append(" ) ");                              
");
        sb.AppendFormat(" sql.Append(" VALUES  ( ");                      
");
        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} ");               
", filedName, splitChar);
            b++;
        }
        sb.AppendFormat(" sql.Append(" ) ");                             
");
        sb.AppendFormat(" #endregion sql                                   
");
        return sb.ToString();
    }
    
    //为某个表生成update语句
    public static string GetUpdateSQL(string tableName, Dictionary<string, string> filedDic)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendFormat("StringBuilder sql = new StringBuilder();           
");
        sb.AppendFormat(" #region sql                                       
");
        sb.AppendFormat(" sql.Append(" Update {0} set   ");               
", 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} "); 
", filedName, splitChar);
            i++;
        }
        sb.AppendFormat(" sql.Append(" Where Id=@Id   "); 
");
        sb.AppendFormat(" #endregion sql                                       
");
        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
}
原文地址:https://www.cnblogs.com/anjun-xy/p/10147701.html