• 一个简单的代码生成器(T4文本模板运用)


    说要写这篇文章有一段时间了,但因为最近各方面的压力导致心情十二分的不好,下班后往往都洗洗睡了。今天痛定思痛,终于把这件拖了很久的事做了。好,不废话了,现在看看"一个简单的代码生成器" .


    先看看界面吧!

    image

    简约到如此,说是代码生成器,估计是要被吐槽的。好吧,借用园子里博友的说法,这只是一粒粟子,如果你愿意,你能看到代码生成器的“种子”。

    这样运行的!

    image

    画了个简图已描述这个简单的代码生成器的工作过程。下面的介绍将以此图展开:

    1)读取数据表的信息:从数据库中读取数据表的信息并转换成要为T4文本模板引擎提供的数据(EntityClassInfo);

    2)将要为T4文本模板引擎提供的数据(EntityClassInfo)作为参数传递给T4文本模板引擎(其实是T4文本模板引擎的宿主,详见T4文本模板转换过程);

    3)T4文本模板引擎读取模板;

    4)T4文本模板引擎将生成的文本返回给应用程序。

     

    代码:

    一、在应用程序和代码中传递的参数的类型

    1)EntityClassInfo.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
     
    namespace EntityInfo
    {
        [Serializable]
        public class EntityClassInfo
        {
            public EntityClassInfo(DataTable dt)
            {
                this.ClassName = dt.TableName;
     
                List<EntityClassPropertyInfo> ropertyListTemp = new List<EntityClassPropertyInfo>();
               
                foreach (DataColumn dcol in dt.Columns)
                {
                    ropertyListTemp.Add(new EntityClassPropertyInfo(dcol));
                }
                this.RopertyList = ropertyListTemp;
     
                List<EntityClassPropertyInfo> primaryKeyListTemp = new List<EntityClassPropertyInfo>();
                List<EntityClassPropertyInfo> notPrimaryKeyListTemp = new List<EntityClassPropertyInfo>(ropertyListTemp);
                foreach (DataColumn dcol in dt.PrimaryKey)
                {
                    primaryKeyListTemp.Add(new EntityClassPropertyInfo(dcol));
                    notPrimaryKeyListTemp.Remove(new EntityClassPropertyInfo(dcol));
                }
                this.PrimaryKeyList = primaryKeyListTemp;
                this.NotPrimaryKeyList = notPrimaryKeyListTemp;
            }
            public string ClassName
            {
                get;
                private set;
            }
            public List<EntityClassPropertyInfo> RopertyList
            {
                get;
                private set;
            }
            public List<EntityClassPropertyInfo> PrimaryKeyList
            {
                get;
                private set;
            }
            public List<EntityClassPropertyInfo> NotPrimaryKeyList
            {
                get;
                private set;
            }
        }
    }

    2)EntityClassPropertyInfo.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
     
    namespace EntityInfo
    {
        [Serializable]
        public class EntityClassPropertyInfo
        {
            public EntityClassPropertyInfo(DataColumn dcol)
            {
                this.PropertyName = dcol.ColumnName;
                this.PropertyType = dcol.DataType.Name;
                this.IsValueType = false;
                if (dcol.DataType.IsValueType)
                {
                    if (dcol.AllowDBNull)
                    {
                        this.PropertyType = this.PropertyType + "?";
                    }
                    else
                    {
                        this.IsValueType = true;
                    }
                }
            }
     
            public string PropertyName
            {
                get;
                private set;
            }
     
            public string PropertyType
            {
                get;
                private set;
            }
     
            public bool IsValueType
            {
                get;
                private set;
            }
     
            public override bool Equals(object obj)
            {
                EntityClassPropertyInfo temp = obj as EntityClassPropertyInfo;
                if (this.PropertyName == temp.PropertyName && this.PropertyType == temp.PropertyType)
                {
                    return true;
                }
                return false;
            }
            
        }
    }

    二、模板

    1)生成实体类的模板:Entity.tt

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".txt" #>
    <#@ import namespace="EntityInfo" #>
    <#@ parameter type="EntityInfo.EntityClassInfo" name="entity" #>
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
     
    /// <summary>
    /// <#= entity.ClassName#> 的摘要说明
    /// </summary>
    public class <#= entity.ClassName#>
    {
        public <#= entity.ClassName#>()
        {
                //
                // TODO: 在此处添加构造函数逻辑
                //
        }
    <#  foreach(EntityClassPropertyInfo property in entity.RopertyList)
        { #>
        private <#= property.PropertyType#> m_<#= property.PropertyName#>;
    <#;
         }
    #>
     
    <#  foreach(EntityClassPropertyInfo property in entity.RopertyList)
        { #>
        public  <#= property.PropertyType#>  <#= property.PropertyName#>
        {
            set { m_<#= property.PropertyName#> = value; }
            get { return m_<#= property.PropertyName#>; }
        }
    <#;
        }
    #>
     
    }

    2)生成DAL层的模板:DataAccess.tt

    <#@ template debug="false" hostspecific="false" language="C#" #>
    <#@ output extension=".txt" #>
    <#@ import namespace="EntityInfo" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ parameter type="EntityInfo.EntityClassInfo" name="entity" #>
    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using MySql.Data.MySqlClient;
    using System.Collections.Generic;
     
    /// <summary>
    /// <#= entity.ClassName#> 的摘要说明
    /// </summary>
    public class <#= entity.ClassName#>DAL
    {
        public <#= entity.ClassName#>DAL()
        {
     
        }
     
        #region 私有方法
     
        #region 根据实体类获取MySqlParameter数组 +MySqlParameter[] FromModel(<#= entity.ClassName#> model)
        private static MySqlParameter[] FromModel(<#= entity.ClassName#> model)
        {
            List<MySqlParameter> parameterList = new List<MySqlParameter>();
    <#  foreach(EntityClassPropertyInfo property in entity.RopertyList)
        { 
    #>        parameterList.Add(new MySqlParameter("@<#=property.PropertyName#>", SQLHelper.ToDBValue(model.<#=property.PropertyName#>)));
    <#; 
        }
    #>
            return parameterList.ToArray();
        }
        #endregion
     
     
        #region 将dr中的数据转换为实体类对象 + <#= entity.ClassName#> ToModel(DataRow dr)
        private static <#= entity.ClassName#> ToModel(DataRow dr)
        {
            <#= entity.ClassName#> model = new <#= entity.ClassName#>();
    <#  foreach(EntityClassPropertyInfo property in entity.RopertyList)
        { 
            if(property.IsValueType)
            {
    #>        model.<#=property.PropertyName#> = Convert.To<#= property.PropertyType#>(SQLHelper.FromDBValue(dr["<#= property.PropertyName #>"]));
    <#;
            }
            else
            {
    #>        model.<#=property.PropertyName#> = SQLHelper.FromDBValue(dr["<#=property.PropertyName#>"]) as <#=property.PropertyType#>;
    <#;
            }
        }
    #>
            return model;
        }
        #endregion
     
        #endregion
     
        #region 增 + int Insert(<#= entity.ClassName#> model)
        public static int Insert(<#= entity.ClassName#> model)
        {
            int result = -1;
            string sql = @"INSERT INTO <#= entity.ClassName#>(<#= string.Join(",",GetSqlInsertInto()) #>) 
                    VALUES(<#= string.Join(",",GetSqlInsertValue()) #>);";
            
            result = SQLHelper.ExecuteNonQuery(sql,FromModel(model));
           
            return result;
        }
        #endregion
     
        #region 删 + int DeleteById(<#= string.Join(",",GetSqlDelVariable()) #>)
        public static int DeleteById(<#= string.Join(",",GetSqlDelVariable()) #>)
        {
            int result = -1;
            string sql = @"DELETE FROM <#= entity.ClassName#> WHERE <#= string.Join(" AND ",GetSqlWhereId()) #>;";
     
            result = SQLHelper.ExecuteNonQuery(sql,<#= string.Join(",",GetSqlDelParameter()) #>);
            
            return result;
        }
        #endregion
        
        #region 改 + int Update(<#= entity.ClassName#> model)
        public static int Update(<#= entity.ClassName#> model)
        {
            int result = -1;
            string sql = @"UPDATE <#= entity.ClassName#> 
                         SET <#= string.Join(",",GetSqlUpdateSet()) #>
                         WHERE <#= string.Join(" AND ",GetSqlWhereId()) #>";
            
            result = SQLHelper.ExecuteNonQuery(sql, FromModel(model));
           
            return result;
        }
        #endregion
        
        #region 查 + int GetCountAll()
        public static int GetCountAll()
        {
            int result = 0;
            string sql = @"SELECT Count(*) FROM <#= entity.ClassName#>;";
     
            result = Convert.ToInt32(SQLHelper.ExecuteScalar(sql));
           
            return result;
        }
        #endregion
     
        #region 查 + List<<#= entity.ClassName#>> GetBySql(string sql,params MySqlParameter[] parameters)
        public static List<<#= entity.ClassName#>> GetBySql(string sql,params MySqlParameter[] parameters)
        {
            List<<#= entity.ClassName#>> modelList = new List<<#= entity.ClassName#>>();
            DataTable dt = SQLHelper.ExecuteDataTable(sql,parameters);
            
            foreach (DataRow dr in dt.Rows)
            {
                modelList.Add(ToModel(dr));
            }
            return modelList;
        }
        #endregion
    }
     
    <#+
        private string[] GetSqlInsertInto()
        {
            List<string> propertyNameList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.RopertyList)
            {
                propertyNameList.Add(property.PropertyName);
            }
            return propertyNameList.ToArray();
        }
        private string[] GetSqlInsertValue()
        {
            List<string> propertyNameList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.RopertyList)
            {
                propertyNameList.Add("@" + property.PropertyName);
            }
            return propertyNameList.ToArray();
        }
        private string[] GetSqlDelVariable()
        {
            List<string> propertyList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
            {
                propertyList.Add(property.PropertyType + "  m_" + property.PropertyName);
            }
            return propertyList.ToArray();
        }
        private string[] GetSqlDelParameter()
        {
            List<string> propertyList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
            {
                propertyList.Add("new MySqlParameter(@"" + property.PropertyName + "" ,m_" + property.PropertyName + ")");
            }
            return propertyList.ToArray();
        }
     
        private string[] GetSqlUpdateSet()
        {
            List<string> propertyList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.NotPrimaryKeyList)
            {
                propertyList.Add(property.PropertyName +"=@" + property.PropertyName);
            }
            return propertyList.ToArray();
        }
        private string[] GetSqlWhereId()
        {
            List<string> propertyList= new List<string>();
            foreach(EntityClassPropertyInfo property in entity.PrimaryKeyList)
            {
                propertyList.Add(property.PropertyName +"=@" + property.PropertyName);
            }
            return propertyList.ToArray();
        }
       
     #>

    三、代码生成四步走:

    1)从数据表信息 =》EntityClassInfo:

    DataTable dt = SQLHelper.ExecuteDataTable(SQLHelper.GetConnectionString(), string.Format("SELECT * FROM {0} LIMIT 0,0", cbbTableName.SelectedValue.ToString()));
    EntityClassInfo entityInfo = new EntityClassInfo(dt);

    备注:

    #region ExecuteTable方法
            public static DataTable ExecuteDataTable(string connectionString,string sql, params MySqlParameter[] parameters)
            {
                using (MySqlConnection conn = new MySqlConnection(connectionString))
                { 
                    using(MySqlCommand cmd = conn.CreateCommand())
                    {
                        cmd.CommandText = sql;
                        cmd.Parameters.AddRange(parameters);
                        using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
                        {
                            using (DataTable dt = new DataTable())
                            {
                                da.Fill(dt);
                                da.FillSchema(dt, SchemaType.Source);   //从数据源中检索架构
                                return dt;
                            }
                        }
                    }
                }
            }
            #endregion

    2)给T4文本模板传参:

    CustomTextTemplatingEngineHost host = new CustomTextTemplatingEngineHost();
    host.Session = new TextTemplatingSession();
    host.Session.Add("entity", classInfo);

    3)读取文本模板:

    string input = File.ReadAllText(templatePath);
    string output = new Engine().ProcessTemplate(input, host);

    4)返回生成的文本:

    string output = new Engine().ProcessTemplate(input, host);

    源码下载(VS2010项目):一个简单的代码生成器(T4文本模板运用)

  • 相关阅读:
    string.format()详解
    微信支持的Authorization code授权模式(公众号开发)(开放平台资料中心中的代公众号发起网页授权)
    HttpClient类详解
    PostgreSQL按年月日分组(关键词:extract time as Year/Month/Day)
    sql中的(case when then else end )的用法(相当于java中的if else)
    模板题 Problem I Link Cut Tree
    BZOJ2555 SubString
    poj3264(简单线段树)
    poj1011(DFS+剪枝)
    poj1042(贪心+枚举)
  • 原文地址:https://www.cnblogs.com/hanzhaoxin/p/3815410.html
Copyright © 2020-2023  润新知