zoukankan      html  css  js  c++  java
  • T4模板生成自定义的实体类

    1、开发工具

      VS2017、Oracle、PL/SQL、T4Toolbox 

      T4模板编辑工具 T4 Editor

    2、数据库查询语句

      2.1、oracle

    --查询当前用户的所有表
    SELECT TABLE_NAME FROM USER_TABLES;
    --根据表名查询表结构数据
    SELECT A.column_name    字段名,                                                                                      
    A.data_type      数据类型,
    A.data_length    长度,
    A.data_precision 整数位,
    A.Data_Scale     小数位,
    A.nullable       允许空值,
    A.Data_default   缺省值,
    B.comments       备注,
    A.TABLE_NAME     表名
    FROM user_tab_columns A, user_col_comments B
    WHERE a.column_name = b.column_name
    AND A.Table_Name = B.Table_Name
    AND A.Table_Name = 'test'
    View Code

      2.2、mysql

    --查询数据库表
        string connectionString = "Data Source=.;Initial Catalog=NFineBase;User ID=sa;Password=hjf19870810;"; 
        SqlConnection conn = new SqlConnection(connectionString); 
        conn.Open(); 
        System.Data.DataTable schema = conn.GetSchema("TABLES"); 
    --通过数据库表查询表结构
    SELECT 表名=sobj.name,字段名=scol.name,字段说明=sprop.[value] FROM syscolumns as scol inner join sys.sysobjects as sobj on scol.id=sobj.id and sobj.xtype='U' and sobj.name<>'dtproperties' left join sys.extended_properties as sprop on scol.id=sprop.major_id and scol.colid=sprop.minor_id where sobj.name='@tableName' and scol.name='@columnName'
    View Code

      2.3、sqlserver

    --SQL 查询所有表名
    SELECT NAME FROM SYSOBJECTS WHERE TYPE='U'
    SELECT * FROM INFORMATION_SCHEMA.TABLES
    --查询表的所有字段名
    SELECT NAME FROM SYSCOLUMNS WHERE ID=OBJECT_ID(' 表名' )
    View Code

    3、生成类文件公用类 ModelAuto.ttinclude

    <#@ assembly name="System.Core"#>
    <#@ assembly name="EnvDTE"#>
    <#@ import namespace="System.Collections.Generic"#>
    <#@ import namespace="System.IO"#>
    <#@ import namespace="System.Text"#>
    <#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
    
    <#+
    
    class Manager
    {
        public struct Block {
            public String Name;
            public int Start, Length;
        }
    
        public List<Block> blocks = new List<Block>();
        public Block currentBlock;
        public Block footerBlock = new Block();
        public Block headerBlock = new Block();
        public ITextTemplatingEngineHost host;
        public ManagementStrategy strategy;
        public StringBuilder template;
        public String OutputPath { get; set; }
    
        public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
            this.host = host;
            this.template = template;
            OutputPath = String.Empty;
            strategy = ManagementStrategy.Create(host);
        }
    
        public void StartBlock(String name) {
            currentBlock = new Block { Name = name, Start = template.Length };
        }
    
        public void StartFooter() {
            footerBlock.Start = template.Length;
        }
    
        public void EndFooter() {
            footerBlock.Length = template.Length - footerBlock.Start;
        }
    
        public void StartHeader() {
            headerBlock.Start = template.Length;
        }
    
        public void EndHeader() {
            headerBlock.Length = template.Length - headerBlock.Start;
        }    
    
        public void EndBlock() {
            currentBlock.Length = template.Length - currentBlock.Start;
            blocks.Add(currentBlock);
        }
    
        public void Process(bool split) {
            String header = template.ToString(headerBlock.Start, headerBlock.Length);
            String footer = template.ToString(footerBlock.Start, footerBlock.Length);
            blocks.Reverse();
            foreach(Block block in blocks) {
                String fileName = Path.Combine(OutputPath, block.Name);
                if (!Directory.Exists(OutputPath))
                {
                    Directory.CreateDirectory(OutputPath);
                }
                if (split) {
                    String content = header + template.ToString(block.Start, block.Length) + footer;
                    strategy.CreateFile(fileName, content);
                    template.Remove(block.Start, block.Length);
                } else {
                    strategy.DeleteFile(fileName);
                }
            }
        }
    }
    
    class ManagementStrategy
    {
        internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
            return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
        }
    
        internal ManagementStrategy(ITextTemplatingEngineHost host) { }
    
        internal virtual void CreateFile(String fileName, String content) {
            File.WriteAllText(fileName, content);
        }
    
        internal virtual void DeleteFile(String fileName) {
            if (File.Exists(fileName))
                File.Delete(fileName);
        }
    }
    
    class VSManagementStrategy : ManagementStrategy
    {
        private EnvDTE.ProjectItem templateProjectItem;
    
        internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
            IServiceProvider hostServiceProvider = (IServiceProvider)host;
            if (hostServiceProvider == null)
                throw new ArgumentNullException("Could not obtain hostServiceProvider");
    
            EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
            if (dte == null)
                throw new ArgumentNullException("Could not obtain DTE from host");
    
            templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
        }
    
        internal override void CreateFile(String fileName, String content) {
            base.CreateFile(fileName, content);
            ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
        }
    
        internal override void DeleteFile(String fileName) {
            ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
        }
    
        private void FindAndDeleteFile(String fileName) {
            foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
                if (projectItem.get_FileNames(0) == fileName) {
                    projectItem.Delete();
                    return;
                }
            }
        }
    }#>
    View Code

    4、T4模板文件

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.Xml" #>
    <#@ assembly name="System.Linq" #>
    <#@ assembly name="System.IO" #>
    <#@ assembly name="$(ProjectDir)LibOracle.ManagedDataAccess.dll" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Collections.Generic"#>
    <#@ import namespace="System.Linq"#>
    <#@ import namespace="Oracle.ManagedDataAccess.Client" #>
    <#@ include file="ModelAuto.ttinclude"#>
    
    <# var manager2 = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile)+"\DefaultModel"}; #>
    <# 
    ModelManager manager = new ModelManager();
    List<string> list=manager.GetTableList();
    #>
    
    <# 
        foreach (var item in list)
        {
            string tableName=item;
            DataTable table= manager.GetTableSchema(tableName);
     #>
    
     <# 
            string tempTableName=manager.FirstCharToUpper(tableName);
            manager2.StartBlock(tempTableName+"Entity.cs");
     #>
    /*********************************************************
    * Copyright (c) 2019
    * All rights reserved.
    * 
    * 文件名称:<#=tempTableName #>.cs
    * 摘    要:业务实体<#=tableName#>的对象
    *
    * 当前版本:1.0.0
    *
    * 作    者:test
    * 完成日期:<#=System.DateTime.Now.ToString("yyyy年MM月dd日") #>
    *
    *********************************************************/
    using System;
    
    namespace Common.Entity
    {
        /// <summary>
        /// 业务实体<#= tableName #>的对象
        /// </summary>
        [Serializable]
        public class <#= tempTableName  #>Entity: BaseEntity, ITableInfo
        {
            #region Parameter List
    <#
    foreach(DataRow row in table.Rows)
    {
    #>
            private <#= manager.TransFromSqlType(row["数据类型"].ToString(),row["整数位"].ToString(),row["小数位"].ToString())#> <#= row["字段名"].ToString().ToLower()#> = <#= manager.MapValue(row["数据类型"].ToString(),row["整数位"].ToString(),row["小数位"].ToString()) #>;    //<#= row["备注"]#>
    
    <#}
    #>
            private string tableName = "<#= tableName #>";
            private string tableSchema = "";
            #endregion
    
            #region Property List
    <#
    foreach(DataRow row in table.Rows)
    {
    #>
            /// <summary>
            /// <#=row["备注"]#>
            /// </summary>   
            public <#= manager.TransFromSqlType(row["数据类型"].ToString(),row["整数位"].ToString(),row["小数位"].ToString())#> <#= manager.FirstCharToUpper(row["字段名"].ToString())#>
            {
                get
                {
                    return <#= row["字段名"].ToString().ToLower() #>;
                }
                set
                {
                    <#= row["字段名"].ToString().ToLower() #> = value;
                }
            }
           
    <#}
    #>
            #endregion
    
            #region ITableInfo Members
            /// <summary>
            /// Database Table Name
            /// </summary>
            public string TableName
            {
                get
                {
                    return tableName;
                }
                set
                {
                    tableName = value;
                }
            }
    
            /// <summary>
            /// Database Table Schema
            /// </summary>
            public string TableSchema
            {
                get
                {
                    return tableSchema;
                }
                set
                {
                    tableSchema = value;
                }
            }
            #endregion
    
        }
    }
    
    <# manager2.EndBlock(); #>
    
    <#
        }  
     #>     
       
    <# manager2.Process(true); #>
    
    <#+
        public class ModelManager
        {
            /// <summary>
            /// 数据库连接字符串
            /// </summary>
           private const string CONNECTION_STRING = "DATA SOURCE=testPRO;USER ID=APP;PASSWORD=APP;";
            /// <summary>
            /// 用户信息表名
            /// </summary>
            private const string PERSONINFO_TABLE_NAME = "USERINFO";
            /// <summary>
            /// 根据表名查询表结构信息
            /// </summary>
            private const string SELECT_SCHEMA_BY_TABLE_NAME = @"SELECT A.column_name    字段名,                                                                                           
                                                                        A.data_type      数据类型,
                                                                        A.data_length    长度,
                                                                        A.data_precision 整数位,
                                                                        A.Data_Scale     小数位,
                                                                        A.nullable       允许空值,
                                                                        A.Data_default   缺省值,
                                                                        B.comments       备注,
                                                                        A.TABLE_NAME     表名
                                                                        FROM user_tab_columns A, user_col_comments B
                                                                        WHERE a.COLUMN_NAME = b.column_name
                                                                        AND A.Table_Name = B.Table_Name
                                                                        AND A.Table_Name = '{0}'";
    
            /// <summary>
            /// 获得数据连接
            /// </summary>
            /// <returns></returns>
            private OracleConnection GetConnection()
            {
                return new OracleConnection(CONNECTION_STRING);
            }
    
            /// <summary>
            /// 得到当前用户的所有表名
            /// </summary>
            /// <returns></returns>
            public List<string> GetTableList()
            {
                string sql = "SELECT * FROM USER_TABLES";
                DataTable dt = OracleHelper.ExecuteDataTable(sql);
                List<string> list = new List<string>();
                if (dt!=null&&dt.Rows.Count>0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        list.Add(dt.Rows[i]["TABLE_NAME"].ToString());
                    } 
                }
                return list;
             }
    
            /// <summary>
            /// 释放连接
            /// </summary>
            /// <param name="con"></param>
            private void ReleaseConnection(OracleConnection con)
            {
                if (con != null)
                {
                    if (con.State == ConnectionState.Open)
                    {
                        con.Close();
                    }
                }
            }
    
            public DataTable GetTableSchema(string tableName)
            {
                DataTable dt;
                using (OracleConnection con = GetConnection())
                {
                    con.Open();
                    OracleCommand cmd = con.CreateCommand();
                    cmd.CommandText = string.Format(SELECT_SCHEMA_BY_TABLE_NAME,tableName);
                    cmd.CommandType = CommandType.Text;
                    OracleDataAdapter adapter = new OracleDataAdapter(cmd);
                    DataSet ds = new DataSet(); 
                    adapter.Fill(ds);
                    dt = ds.Tables[0];
                }
    
                return dt;
            }
    
            public string FirstCharToUpper(string input)
            {
                if (String.IsNullOrEmpty(input))
                    throw new ArgumentException("ARGH!");
                return input.First().ToString().ToUpper() + input.Substring(1).ToLower();
            }
    
            public string MapValue(string type, string number, string small)
            {
                string dataType = TransFromSqlType(type, number, small);
                if (string.Equals(dataType, "string", StringComparison.OrdinalIgnoreCase))
                {
                    return "null";
                }
                else
                {
                    return dataType + ".MinValue";
                }
            }
    
            /// <summary>
            /// SQL[不完善,需要的自己改造]
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            public string TransFromSqlType(string type, string number, string small)
            {
                if (string.IsNullOrEmpty(type))
                {
                    return string.Empty;
                }
                if (string.Equals(type, "number", StringComparison.OrdinalIgnoreCase))
                {
                    if (!string.IsNullOrEmpty(number))
                    {
                        if (!string.IsNullOrEmpty(small) && int.Parse(small) > 0)
                        {
                            return "decimal";
                        }
                        if (int.Parse(number) >= 10 && (string.IsNullOrEmpty(small) || (!string.IsNullOrEmpty(small)&&int.Parse(small)==0)))
                        {
                            return "Int64";
                        }
                        else if (int.Parse(number) < 10 && (string.IsNullOrEmpty(small) || (!string.IsNullOrEmpty(small) && int.Parse(small) == 0)))
                        {
                            return "Int32";
                        }
                       
                    }
                    else
                    {
                        return "Int32";
                    }
                }
                if (string.Equals(type, "date", StringComparison.OrdinalIgnoreCase))
                {
                    return "DateTime";
                }
                else if (string.Equals(type, "nvarchar2", StringComparison.OrdinalIgnoreCase) || string.Equals(type, "char", StringComparison.OrdinalIgnoreCase))
                {
                    return "string";
                }
                return "string";
            }
    
        }
    #>
    
    <#+ 
    public class OracleHelper
        {
    
            private static string oracleConnectionStr = "DATA SOURCE=testPRO;USER ID=APP;PASSWORD=APP;";
            public static DataTable ExecuteDataTable(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        DataTable dt = new DataTable();
                        OracleDataAdapter adapter = new OracleDataAdapter(command);
                        adapter.Fill(dt);
                        return dt;
                    }
                }
            }
    
            public static int ExecuteNonQuery(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteNonQuery();
                    }
                }
            }
    
            public static object ExecuteScalar(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteScalar();
                    }
                }
            }
        }
    
     #>
    View Code

     生成文件如下图

    5、T4模板语法

      主要分为 1指令 2文本块 3指令块

      <# 标准控制块 #> 可以包含语句。
      <#= 表达式控制块 #> 可以包含表达式。
      <#+ 类功能控制块 #> 可以包含方法、字段和属性,就像一个类的内部

      5.1 指令

      主要包括template, output, assembly, import, include等类型

      $(SolutionDir):当前项目所在解决方案目录
      $(ProjectDir):当前项目所在目录
      $(TargetPath):当前项目编译输出文件绝对路径
      $(TargetDir):当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

      5.2 文本块

      文本块直接向输出文件插入文本。 文本块没有特殊格式,就像我们刚才初体验中写的类一样。

      5.3 指令块

      标准控制块:

    <#
        for(int i = 0; i < 4; i++)
        {
    #>
    Hello World!
    <#
        } 
    #>
    View Code

      表达式控制块:

    <#
        XmlDocument xDoc = new XmlDocument();
        xDoc.Load(@"E:CSharpOverview.xml");
        XmlAttributeCollection attributes = xDoc.Attributes;
        if (attributes != null)
        {
           foreach (XmlAttribute attr in attributes)
           {
    #><#= attr.Name #><#
           }
        }
    #>
    View Code

      类功能控制块:

    <#+ 
    public class OracleHelper
        {
    
            private static string oracleConnectionStr = "DATA SOURCE=testPRO;USER ID=APP;PASSWORD=APP;";
            public static DataTable ExecuteDataTable(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        DataTable dt = new DataTable();
                        OracleDataAdapter adapter = new OracleDataAdapter(command);
                        adapter.Fill(dt);
                        return dt;
                    }
                }
            }
    
            public static int ExecuteNonQuery(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteNonQuery();
                    }
                }
            }
    
            public static object ExecuteScalar(string sql, params OracleParameter[] paramList)
            {
                using (OracleConnection conn = new OracleConnection(oracleConnectionStr))
                {
                    conn.Open();
                    using (OracleCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteScalar();
                    }
                }
            }
        }
    
     #>
    View Code

    更多的T4模板语法参考 https://docs.microsoft.com/zh-cn/visualstudio/modeling/code-generation-and-t4-text-templates?view=vs-2015

    参考:https://www.cnblogs.com/fenglingyi/p/5927082.html

       https://www.cnblogs.com/maiaimei/p/8994552.html

  • 相关阅读:
    [译文] 实体与值对象到底是不是一回事?
    实现 WebApi 自托管服务宿主于 WinForms 及其交互
    [译文] C# 8 已成旧闻, 向前, 抵达 C# 9!
    [译文] 为什么你在 C# 里总是应该使用 "var" 关键字
    通过设置iis在局域网中访问网页
    windows 10 安装使用kafka
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 2) 定义命名化和类型化的客户端
    Asp.net Core 2.0 OpenId Connect Handler缺失Claims?
  • 原文地址:https://www.cnblogs.com/ZJ199012/p/12009781.html
Copyright © 2011-2022 走看看