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


先看看界面吧!

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

这样运行的!

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

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. PHP 字符串编码的转换

    原文链接:http://mangguo.org/php-string-encoding-convert-and-detect/ GBK 和 UTF-8 编码的转换是一个非常恶心的事情,比如像 PHP ...

  2. 1052: 旋转单词(words)

    #include <iostream> #include <iomanip> #include <cstdlib> #include <string> ...

  3. achartengine(Google给android提供的画图工具包)的介绍和使用

    AChartEngine(ACE)是Google为Android提供的一个开源绘制工具包.它集成了绘制多种图形的功能:折线图.散点图.气泡图.柱状图.饼图.仪表图等图形. 下载地址:http://do ...

  4. BI Admin Tools和目录管理器的连接配置

    BI管理(Admin Tools): BI Server 的管理工具,用来创建维护模型,并且能够管理安全,会话,变量等等.是用的最多的一个管理工具:这个工具可以编辑 rpd 文件也可以在线通过 ODB ...

  5. idea 配置svn

        1.情景展示 idea安装好后,如何配置svn? 2.分析 由于没有针对idea的svn插件,因此只能选择安装svn的客户端. 3.解决方案 第一步:下载小乌龟SVN客户端: 官网地址:htt ...

  6. 〖Linux〗bash和expect执行ssh命令行sshcmd.exp

    #!/usr/bin/expect -f # sudo apt-get install expect # ./ssh.exp user passwd server set user [lrange $ ...

  7. python模块之imghdr(识别不同格式的图片文件)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python模块之imghdr(识别不同格式的图片文件) import imghdr '''>> ...

  8. Mybatis-Dao层开发之Mapper接口

    Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法. Mapper接口开发 ...

  9. Intellij Idea 导入多个maven项目展示在左侧栏Maven Projects

    刚刚要开始从eclipse切换成idea,据说idea功能强大,可是刚刚开始使用很多不习惯,导入第二个maven项目时之前的项目就没了,比较苦恼,下面介绍下导入多个maven项目展示在左侧栏Maven ...

  10. Centos7 修改终端文字显示颜色

    Centos7的配色方案主要是以下几个文件 -rw-r--r--. root root 11月 /etc/DIR_COLORS -rw-r--r--. root root 10月 : /etc/DIR ...