zoukankan      html  css  js  c++  java
  • 基于数据库的vs2019的T4模版代码生成器(一)基于sqlserver数据库

    总体介绍

    参考文档:

    https://www.cnblogs.com/laozhang-is-phi/p/9757999.html

    只想用 ADO.NET 搭建多层框架,动软代码生成器是一个不错的选择。

    T4 (Text Template Transformation Toolkit) 是微软官方在 VisualStudio 2008+ 中开始使用的代码生成引擎。在 Visual Studio 中,“T4 文本模板”是由一些文本块和控制逻辑组成的混合模板,它可以生成文本文件。 在 Visual C# 或 Visual Basic 中,控制逻辑编写为程序代码的片段。生成的文件可以是任何类型的文本,例如网页、资源文件或任何语言的程序源代码。现在的VS中只要与代码生成相关的场景基本上都能找T4的身影,比如MVC的视图模板,Entity Framwork的DataContext模板等等。

     这里就不具体讲解 T4 语法了,大家可以自行学习,其实很简单,主要还是 C# 代码,下边你看过之后就能懂了,咱们首先先实现之前留下的一个伏笔 —— 将我们的数据库表利用T4 模板生成实体类,也就是 DbFirst。

    1、首先在我们的项目中,新建一个类库 Xwy.Core.FrameWorkT4 

    2、在该类库下,新建文件夹 Xwy.Core.FrameWorkT4.Entity,用于单独存放我们的模板以及生成的实体类文件

    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"#>
    
    <#+
    //定义管理者 manager 实体类
    class Manager
    {
        //定义一个 block 块,主要是应用在批量生产中
        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; }
        //构造函数,包含 host主机,模板,输出路径,创建管理策略
        public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
            this.host = host;
            this.template = template;
            OutputPath = String.Empty;
            strategy = ManagementStrategy.Create(host);
        }
        //开辟一个 block 块
        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);
        }
        //定义进程,用来将所有的 blocks 块执行出来
        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;
                }
            }
        }
    }#>

    5 DbHelper.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"#>
    
    <#+
    //定义管理者 manager 实体类
    class Manager
    {
        //定义一个 block 块,主要是应用在批量生产中
        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; }
        //构造函数,包含 host主机,模板,输出路径,创建管理策略
        public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
            this.host = host;
            this.template = template;
            OutputPath = String.Empty;
            strategy = ManagementStrategy.Create(host);
        }
        //开辟一个 block 块
        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);
        }
        //定义进程,用来将所有的 blocks 块执行出来
        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;
                }
            }
        }
    }#>

    6 模板文件Entity.tt

    //如果要获取主机信息,记得把 hostspecific 设置成true
    <#@ template debug="false" hostspecific="True" language="C#" #>
    <#@ output extension=".cs" #>
    
    //导入命名空间组件
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.xml" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.Data.SqlClient" #>
    <#@ import namespace="System.Data" #>
    <#@ assembly name="System.Core.dll" #>
    <#@ assembly name="System.Data.DataSetExtensions.dll" #>
    <#@ import namespace="System" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Collections.Generic" #>
    <#@ import namespace="System.IO" #>
    
    //引入我们的公共模板文件
    <#@ include file="$(ProjectDir)DbHelper.ttinclude"  #>
    <#@ include file="$(ProjectDir)ModelAuto.ttinclude"    #>
    
    //定义我们的输出文件夹
    <# 
        var OutputPath1 = Path.GetDirectoryName(Host.TemplateFile)+"\work";
        if (!Directory.Exists(OutputPath1))
        {
            Directory.CreateDirectory(OutputPath1);
        }
         var manager = new Manager(Host, GenerationEnvironment, true) { OutputPath = OutputPath1 }; 
    #>
    
    
    //--------------------------------------------------------------------
    //     此代码由T4模板自动生成
    //    老张的哲学 生成时间 <#=DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#> 
    //     注意更新后会改变相应代码。
    //--------------------------------------------------------------------
    <# 
        var tableName=config.TableName;//获取config配置中的表名,为单一生产使用
     #>
    <# 
    if(tableName!=""){//如果表名有值,表示是生成单一文件
        #>  
    //引用命名空间
    using System;
    namespace Blog.Core.FrameWork.Entity
    {    
        /// <summary>
        /// <#=tableName#>
        /// </summary>    
        public class <#=tableName#>//可以在这里加上基类等
        {
        //将全部字段遍历出来
    <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, config.TableName)){#>
          public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName#> { get; set; }
    <#}#> 
        }
    }
    //如果为空,表示要将整个数据库都生成出来
    <# 
        } else{ 
    
        #>
        //连接数据库,打开 connect 连接
    <# 
        SqlConnection conn = new SqlConnection(config.ConnectionString); 
        conn.Open(); 
        System.Data.DataTable schema = conn.GetSchema("TABLES"); 
     #>
     //遍历全部数据库表
    <# 
        foreach(System.Data.DataRow row in schema.Rows) 
        {  #>   
    
        //开始启动block块,参数是实体类文件名
        <# 
            manager.StartBlock(row["TABLE_NAME"]+".cs");
         #>
    using System;
    namespace Blog.Core.FrameWork.Entity
    {    
        /// <summary>
        /// <#=tableName#>
        /// </summary>    
        public class <#=row["TABLE_NAME"].ToString()#>//可以在这里加上基类等
        {
        //将该表下的字段都遍历出来,可以自定义获取数据描述等信息
    <# foreach(DbColumn column in DbHelper.GetDbColumns(config.ConnectionString, config.DbDatabase, row["TABLE_NAME"].ToString() )){ #>
    
          public <#= column.CSharpType#><# if(column.CommonType.IsValueType && column.IsNullable){#>?<#}#> <#=column.ColumnName #> { get; set; }
    <#}#> 
    
        }
    }
        <# 
            manager.EndBlock(); 
            } 
            manager.Process(true);
        }
        #>
  • 相关阅读:
    Seasar2:SAStruts:View(JSP)
    Seaser2:SAStruts:エラーメッセージの設定
    Seaser2:SAStruts:アクションとアクションフォーム(Struts)
    SAStruts アクションにJSONを返すメソッドを作成してみる
    S2JDBC テーブルを利用した独自仕様のid採番メソッド
    【C++ 异常】error: jump to case label [fpermissive]
    MusicXML 3.0 (15) 倚音
    MusicXML 3.0 (9) 小节线、反复线、终止线
    MusicXML 3.0 (13) 歌词
    MusicXML 3.0 (10) 换行、换页
  • 原文地址:https://www.cnblogs.com/xiewenyu/p/13111754.html
Copyright © 2011-2022 走看看