zoukankan      html  css  js  c++  java
  • C#编写T4模板实现数据表到实体类的映射

    开发工具:VS2017、SQLServer2017、PL/SQL

    准备工作:下载并安装T4Toolbox

    1、创建文件EntityTemplate.tt、EntityProperties.tt,注意选择这个哦

    EntityTemplate.tt内容如下:

    <#+
    public class EntityTemplate : CSharpTemplate
    {
    	private string tableName;
    	private string colProperties;
    
    	public EntityTemplate(string tableName,string colProperties)
        {
            this.tableName = tableName;
    		this.colProperties = colProperties;
        }
    
    	public override string TransformText()
    	{
    		base.TransformText();
    #>
    using System;
    
    namespace Model.DefaultDB
    {
        public class <#= tableName #>
        {
            <#= colProperties #>
        }
    }
    <#+
            return this.GenerationEnvironment.ToString();
    	}
    }
    #>
    

     EntityProperties.tt内容如下:

    <#+
    public class EntityProperties : CSharpTemplate
    {
    
    	private string colName;
    	private string colType;
    	private string colDesc;
    
    	public EntityProperties(string colName,string colType,string colDesc)
        {
            this.colName = colName;
    		this.colType = colType;
    		this.colDesc = colDesc;
        }
    
    	public string DbTypeConvert(string dbType)
    	{
    		dbType = dbType.ToString().ToLower();
    		switch (dbType)
    		{
    			case "char":
    			case "varchar":
    			case "varchar2":
    			case "nvarchar":
    			case "nvarchar2":
    			case "clob":
    			case "nclob":
    			case "xmltype":
    				{
    					return "string";
    				}
    			case "date":
    			case "datetime":
    			case "datetime2":
    				{
    					return "DateTime";
    				}
    			case "tinyint":
    				{
    					return "byte";
    				}
    			case "number":
    				{
    					return "int";
    				}
    			case "uniqueidentifier":
    				{
    					return "Guid";
    				}
    			default:
    				{
    					return dbType;
    				}
    		}
    	}
    
    	public override string TransformText()
    	{
    		base.TransformText();
    #>
            /// <summary>
            /// <#= colDesc #>
            /// </summary>
            public <#= DbTypeConvert(colType) #> <#= colName #> { get; set; }
    <#+
            return this.GenerationEnvironment.ToString();
    	}
    }
    #>
    

     2、创建SQLServerDefaultDB.tt、OracleDefaultDB.tt,模板为vs自带的

    SQLServerDefaultDB.tt内容如下:

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ assembly name="$(SolutionDir)LibCore.dll" #>
    <#@ assembly name="$(SolutionDir)LibDal.dll" #>
    <#@ assembly name="System.Core" #>
    <#@ assembly name="System.Data" #>
    <#@ import namespace="Core" #>
    <#@ import namespace="Dal" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Text" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#@ include file="T4Toolbox.tt" #>
    <#@ include file="EntityTemplate.tt" #>
    <#@ include file="EntityProperties.tt" #>
    <#
    	//连接字符串
    	string connStr = "Data Source=.;Initial Catalog=DefaultDB;enlist=false;User ID=sa;Password=123456";
    
    	//查询所有用户表
    	string sqlQueryTables = "select 表名=o.name from sys.sysobjects as o where o.xtype='U' and o.name<>'dtproperties' order by o.name";
    
    	//查询表定义
    	string sqlQueryColumns = @"
    SELECT
    表名=o.name,
    字段名 = c.name,
    类型 = t.name,
    说明 = p.[value] 
    FROM syscolumns as c
    inner join sys.sysobjects as o on c.id = o.id and o.xtype = 'U' and o.name <> 'dtproperties'
    inner join sys.systypes as t on c.xusertype = t.xusertype
    left join sys.extended_properties as p on c.id = p.major_id and c.colid = p.minor_id
     order by o.name";
    
    	//替换T4模板中多余的注释
    	Regex reg1 = new Regex("// <autogenerated>
    ");
    	Regex reg2 = new Regex("//   This file was generated by T4 code generator SQLServerDefaultDB.tt.
    ");
    	Regex reg3 = new Regex("//   Any changes made to this file manually will be lost next time the file is regenerated.
    ");
    	Regex reg4 = new Regex("// </autogenerated>
    ");
    
    	//创建实体类存放路径
        string curPath = Path.GetDirectoryName(Host.TemplateFile);
        string defaultDBPath = Path.Combine(curPath, "DefaultDB");
        if(!Directory.Exists(defaultDBPath))
        {
            Directory.CreateDirectory(defaultDBPath);
        }
    
    	var dbProvider = new SQLServerService(connStr);
    
    	var dsTableName = dbProvider.ExecuteQuery(sqlQueryTables);
    	var dsColumnInfo = dbProvider.ExecuteQuery(sqlQueryColumns);
    
    	foreach (DataRow rTableName in dsTableName.Tables[0].Rows)
    	{
    		var tableName = rTableName["表名"].ToString();
    		StringBuilder colProperties = new StringBuilder();
    		foreach (DataRow rColumnInfo in dsColumnInfo.Tables[0].Rows)
    		{
    			if (rColumnInfo["表名"].ToString() == tableName)
    			{
    				EntityProperties prop = new EntityProperties(rColumnInfo["字段名"].ToString(),rColumnInfo["类型"].ToString(),rColumnInfo["说明"].ToString());
    				var propStr = prop.TransformText();
    				var propStrNew = reg1.Replace(propStr, "");
    				propStrNew = reg2.Replace(propStrNew, "");
    				propStrNew = reg3.Replace(propStrNew, "");
    				propStrNew = reg4.Replace(propStrNew, "");
    				colProperties.AppendLine(propStrNew);
    			}
    		}
    
    		string fileName = string.Format(@"{0}{1}.cs", defaultDBPath, tableName);
    		EntityTemplate template = new EntityTemplate(tableName,colProperties.ToString());
            template.Output.Encoding = Encoding.UTF8;
            template.RenderToFile(fileName);
    	}
     #>
    

     OracleDefaultDB.tt内容如下:

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ assembly name="$(SolutionDir)LibCore.dll" #>
    <#@ assembly name="$(SolutionDir)LibDal.dll" #>
    
    <#@ assembly name="System.Core" #>
    <#@ assembly name="System.Data" #>
    <#@ import namespace="Core" #>
    <#@ import namespace="Dal" #>
    
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Text" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    <#@ include file="T4Toolbox.tt" #>
    <#@ include file="EntityTemplate.tt" #>
    <#@ include file="EntityProperties.tt" #>
    <#
    	//连接字符串
    	string connStr = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=00.000.00.000)(PORT=0000))(CONNECT_DATA=(SID=GZTNS)));User ID=DefaultDB;Password=123456";
    
    	//查询所有用户表
    	string sqlQueryTables = "select distinct o.table_name 表名 from user_tab_columns o order by o.table_name";
    
    	//查询表定义
    	string sqlQueryColumns = @"
    select 
    o.table_name 表名,
    c.column_name 字段名,
    o.data_type 类型,
    c.comments 说明 
    from user_col_comments c 
    inner join user_tab_columns o on c.column_name = o.column_name and c.table_name = o.table_name  order by o.table_name";
    
    	//替换T4模板中多余的注释
    	Regex reg1 = new Regex("// <autogenerated>
    ");
    	Regex reg2 = new Regex("//   This file was generated by T4 code generator OracleDefaultDB.tt.
    ");
    	Regex reg3 = new Regex("//   Any changes made to this file manually will be lost next time the file is regenerated.
    ");
    	Regex reg4 = new Regex("// </autogenerated>
    ");
    
    	//创建实体类存放路径
        string curPath = Path.GetDirectoryName(Host.TemplateFile);
        string defaultDBPath = Path.Combine(curPath, "DefaultDB_Oracle");
        if(!Directory.Exists(defaultDBPath))
        {
            Directory.CreateDirectory(defaultDBPath);
        }
    
    	var dbProvider = new OracleService(connStr);
    
    	var dsTableName = dbProvider.ExecuteQuery(sqlQueryTables);
    	var dsColumnInfo = dbProvider.ExecuteQuery(sqlQueryColumns);
    
    	foreach (DataRow rTableName in dsTableName.Tables[0].Rows)
    	{
    		var tableName = rTableName["表名"].ToString();
    		StringBuilder colProperties = new StringBuilder();
    		foreach (DataRow rColumnInfo in dsColumnInfo.Tables[0].Rows)
    		{
    			if (rColumnInfo["表名"].ToString() == tableName)
    			{
    				EntityProperties prop = new EntityProperties(rColumnInfo["字段名"].ToString(),rColumnInfo["类型"].ToString(),rColumnInfo["说明"].ToString());
    				var propStr = prop.TransformText();
    				var propStrNew = reg1.Replace(propStr, "");
    				propStrNew = reg2.Replace(propStrNew, "");
    				propStrNew = reg3.Replace(propStrNew, "");
    				propStrNew = reg4.Replace(propStrNew, "");
    				colProperties.AppendLine(propStrNew);
    			}
    		}
    
    		string fileName = string.Format(@"{0}{1}.cs", defaultDBPath, tableName);
    		EntityTemplate template = new EntityTemplate(tableName,colProperties.ToString());
            template.Output.Encoding = Encoding.UTF8;
            template.RenderToFile(fileName);
    	}
     #>
    

     实体类存放路径自己定义,搞定后,选择SQLServerDefaultDB.tt或OracleDefaultDB.tt,右击->运行自定义工具

    如果数据库是SQLServer的话,可以打开profiler看下

    PS:数据库访问部分,是ADO.NET的。若oracle,需要引用Oracle.DataAccess.dll。

    最后生成的结果图如下:

    DefaultDB_Oracle,184个数据表,16/17秒瞬间搞定~~

    搬砖,努力搬砖。

  • 相关阅读:
    CSU1256 天朝的单行道(spfa)
    WordPress For SAE进入后台
    Android studio 使用NDK工具实现JNI编程
    android动画具体解释一 概述
    VC6.0编译DLL,使用VS2010调用问题及解决方法
    android 地址控件概述
    android 多线程概述
    android 中的 window,view,activity具体关系
    比较windows phone程序启动和android程序启动原理
    比较windows phone 的回退事件与android的回退事件
  • 原文地址:https://www.cnblogs.com/maiaimei/p/8994552.html
Copyright © 2011-2022 走看看