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


先看看界面吧!

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

这样运行的!

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

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文本模板运用)

一个简单的代码生成器(T4文本模板运用)的更多相关文章

  1. 编写 T4 文本模板

    文本模板由以下部件组成: 1)指令 - 控制模板处理方式的元素. 2)文本块 - 直接复制到输出的内容. 3)控制块 - 向文本插入可变值并控制文本的条件或重复部件的程序代码. 指令: 指令是控制模板 ...

  2. T4 文本模板编写准则

    如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助. 它们并不是一成不变的规则. 设计时 T4 模板准则 设计时 T4 模板是在设计时在 Visua ...

  3. 使用 T4 文本模板生成设计时代码

      使用设计时 T4 文本模板,您可以在 Visual Studio 项目中生成程序代码和其他文件. 通常,您编写一些模板,以便它们根据来自模型的数据来改变所生成的代码. 模型是包含有关应用程序要求的 ...

  4. T4文本模板转换过程

    T4文本模板转换过程将文本模板文件作为输入,生成一个新的文本文件作为输出. 例如,可以使用文本模板生成 Visual Basic 或 C# 代码,还可以生成 HTML 报告. 有三个组件参与这一过程: ...

  5. 动手写一个简单的Web框架(模板渲染)

    动手写一个简单的Web框架(模板渲染) 在百度上搜索jinja2,显示的大部分内容都是jinja2的渲染语法,这个不是Web框架需要做的事,最终,居然在Werkzeug的官方文档里找到模板渲染的代码. ...

  6. T4文本模板

    <#...#> 可以包含语句 <#=...#>  用于表达式,提供“输出”操作 <#+ ...> 使用类功能控制块向文本模板添加方法.属性.字段,必须作为文件中最后 ...

  7. 一个简单的Android富文本TextView实现

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px Helvetica; color: #555555 } p.p2 { margin: 0.0p ...

  8. 一个简单的Dump转文本工具—Dump2Text

    每次电脑重装都得烦心,要把庞大的IDE重新配置一次,正准备安装Visual Stdio 2010,上网找镜像的时候发现,Visual Stdio 2013推出了Community版,不仅没有lite掉 ...

  9. MVC开发T4代码生成之一----文本模板基础

    T4文本模板 T4全写为Text Template Transformation Toolkit,是一种编程辅助工具,用来使程序代码自(懒)动(猿)生(福)成(利)的工具.MVC开发中大量使用了T4模 ...

随机推荐

  1. 10分钟精通require.js

    require.js的诞生,就是为了解决这两个问题:(1)实现js文件的异步加载,避免网页失去响应:(2)管理模块之间的依赖性,便于代码的编写和维护. 实例下载:require.js应用实例 一.re ...

  2. asp.net正则表达式类的定义

    using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; using ...

  3. SqlServer判断表、列不存在则创建

    一.表不存在则创建: if not exists (select * from sysobjects where id = object_id('mytab') and OBJECTPROPERTY( ...

  4. HttpClient Restful Post 请求

    public static void main(String[] args) { SbVo sb = new SbVo(); sb.setBusiness("SB"); sb.se ...

  5. PSQL命令小结

    经常使用psql查询数据,现在总结几个常用的命令参数,供以后参考 -h   数据库地址 -U   数据库用户名 -t   不打印字段等信息 -c   执行的SQL语句 -s   单步执行,就是执行的时 ...

  6. JAVA设计模式——第 7 章 门面模式【Facade Pattern】(转)

    好,我们继续讲课.大家都是高智商的人,都写过纸质的信件吧,比如给女朋友写情书什么的,写信的过程大家都还记得吧,先写信的内容,然后写信封,然后把信放到信封中,封好,投递到信箱中进行邮递,这个过程还是比较 ...

  7. 深入理解JVM内存区域与内存分配

    前言:这是一篇关于JVM内存区域的文章,由网上一些有关这方面的文章和<深入理解Java虚拟机>整理而来,所以会有些类同的地方,也不能保证我自己写的比其他网上的和书本上的要好,也不可能会这样 ...

  8. 前端安全系列之二:如何防止CSRF攻击

    原文:https://my.oschina.net/meituantech/blog/2243958 背景 随着互联网的高速发展,信息安全问题已经成为企业最为关注的焦点之一,而前端又是引发企业安全问题 ...

  9. Java获取本机IP

    try { Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); whil ...

  10. excel主题使文档更加具有专业化

    如上图所示,表格或图表有很多的配色方案. 1.每个主题,会有一套配色方案,而且这些配色方案相对来讲都是比较协调统一的, 2.页面布局----主题,选择好主题之后再套用配色方案