zoukankan      html  css  js  c++  java
  • 在.Net Core中使用T4工具生成实体文件

    多说无益直接代码伺候。

    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 (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;
                }
            }
        }
    }#>

    创建一个*.tt模板文件,实例代码数据库使用的Oracle数据库。模板内容和数据库连接需要自行修改。

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.Data.OracleClient" #>
    <#@ assembly name="System.Xml" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.Data.OracleClient" #>
    <#@ import namespace="System.Collections.Generic"#>
    <#@ include file="ModelAuto.ttinclude"#>
    <# var manager2 = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile)}; #>
    <# 
    ModelManager manager = new ModelManager();
    List<string> list=manager.GetTableList();
    #>
    
    <# 
        foreach (var item in list)
        {
            string tableName=item;
            DataTable table= manager.GetTableSchema(tableName);
     #>
    
     <# 
            manager2.StartBlock(tableName+".cs");
     #>
    using System;
    using Dapper.Contrib.Extensions;namespace ABC.Entitys
    {
        /// <summary>
        /// 
        /// </summary>
        [Table("<#= tableName #>")]
        public class <#= tableName #> : Entity
        {
    <#
    foreach(DataRow row in table.Rows)
    {
    #>
           /// <summary>
           /// <#=row["备注"]#>
           /// </summary>
    <# if(row["主键"].ToString() == "1") { #>       [ExplicitKey]
    <#} #>       public <#= manager.TransFromSqlType(row["数据类型"].ToString())#> <#=row["字段名"]#> { get; set; }
    
    <#}
    #>
        }
    }
    
    <# manager2.EndBlock(); #>
    
    <#
        }  
     #>     
       
    <# manager2.Process(true); #>
    
    <#+
        public class ModelManager
        {
            /// <summary>
            /// 根据表名查询表结构信息
            /// </summary>
            private const string SELECT_SCHEMA_BY_TABLE_NAME = @"
            with C as(
              select c1.table_name, c2.column_name, c2.position
                from user_constraints c1, user_cons_columns c2
               where c1.constraint_name = c2.constraint_name
                 and c2.position=1
                 and c1.constraint_type = 'P'
            )
            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     表名,
                   (case when C.column_name is null then 0 else 1 end)      主键
              FROM user_tab_columns A
                join user_col_comments B on A.COLUMN_NAME = B.column_name and A.Table_Name = B.Table_Name
                left join C on C.Table_Name = A.Table_Name and C.column_name = A.column_name
            where A.Table_Name = '{0}'";
    
    
            /// <summary>
            /// 得到当前用户的所有表名
            /// </summary>
            /// <returns></returns>
            public List<string> GetTableList()
            {
                string sql = "SELECT * FROM USER_TABLES t";
                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;
             }
    
            public DataTable GetTableSchema(string tableName)
            {
                string sql = string.Format(SELECT_SCHEMA_BY_TABLE_NAME,tableName);
                DataTable dt = OracleHelper.ExecuteDataTable(sql);
                return dt;
            }
    
            /// <summary>
            /// SQL[不完善,需要的自己改造]
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            public string TransFromSqlType(string type)
            {
                if (string.IsNullOrEmpty(type))
                {
                    return string.Empty;
                }
                if (string.Equals(type, "number", StringComparison.OrdinalIgnoreCase))
                {
                    return "decimal";
                }
                if (string.Equals(type, "date", StringComparison.OrdinalIgnoreCase))
                {
                    return "DateTime";
                }
                else if (string.Equals(type, "nvarchar2", StringComparison.OrdinalIgnoreCase))
                {
                    return "string";
                }
                return "string";
            }
        }
    #>
    
    <#+ 
    public class OracleHelper
        {
    
            private static string oracleConnectionStr = "data source= (DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = eclorcl)));user id=abc;password=123456";
            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();
                    }
                }
            }
        }
    
     #>

    在vs2019中保存*.tt文件的时候会自动提示运行。

    OracleClient
  • 相关阅读:
    静态资源分析 ------ CocosCreator
    性能分析 ------ CPU运行卡点
    神犇的blog
    0x01-1 原码 反码 补码 概念 原理 详解
    埃拉托色尼素数筛法(转)
    Miller-Rabin概率素数测试算法(转)
    欧拉函数(转)
    中国剩余定理(孙子定理)详解 (转)
    负数取模(转)
    HDU1430 BFS + 打表 + 康托展开(转)
  • 原文地址:https://www.cnblogs.com/letnet/p/13489679.html
Copyright © 2011-2022 走看看