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


先看看界面吧!

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

这样运行的!

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

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. js实现双击滚屏效果

    <body onDblClick="s=setInterval('scrollBy(0,2)',50)" onMousedown="clearInterval(s) ...

  2. Using a Microsoft Account to Logon and Resulting Internet Communication in Windows 8

    Using a Microsoft Account to Logon and Resulting Internet Communication in Windows 8 此主题尚未评级 - 评价此主题 ...

  3. Summarizing NUMA Scheduling两篇文章,解释得不错

    http://vxpertise.net/2012/06/summarizing-numa-scheduling/ Sitting on my sofa this morning watching S ...

  4. Linux下设置进程使用指定核的CPU

    一.原因: 我们不能任由操作系统负载均衡,因为我们自己更了解自己的程序,所以,我们可以手动地为其分配CPU核,而不会过多地占用CPU0,或是让我们关键进程和一堆别的进程挤在一起. 二.查看方法: 1. ...

  5. 016-Go Iris Restful测试

    1:data/data.go package data import( "fmt" "database/sql" _"github.com/lib/p ...

  6. linux下时间有关的函数和结构体

    1.时间类型.Linux下常用的时间类型有6个:time_t,struct timeb, struct timeval,struct timespec,clock_t, struct tm. (1) ...

  7. JdbcTemplate应用学习

    一.Spring对不同的持久化支持: Spring为各种支持的持久化技术,都提供了简单操作的模板和回调 ORM持久化技术 模板类 JDBC org.springframework.jdbc.core. ...

  8. android使用百度地图SDK获取定位信息

    本文使用Android Studio开发. 获取定位信息相对简单.我们仅仅须要例如以下几步: 第一步,注冊百度账号,在百度地图开放平台新建应用.生成API_KEY.这些就不细说了,请前往这里:titl ...

  9. java 如何对由json对象构成的数组形式的字符串进行遍历?

      1.情景展示 现在已知字符串为: [{"name":"微微笑","img":"http://zos.alipayobjects ...

  10. django之创建第11个项目-页面整合

    目的:将如下众多html页面整合到一个index.html页面中. 百度云盘:django之创建第11个项目-页面整合 用下面的方式实现: <!DOCTYPE html> <head ...