T4 TemplateFileManager 输出到项目文件夹

Posted

技术标签:

【中文标题】T4 TemplateFileManager 输出到项目文件夹【英文标题】:T4 TemplateFileManager output to projectfolder 【发布时间】:2021-03-04 18:59:47 【问题描述】:

我对 C# 和 T4 完全陌生。但作为一个数据专家,我想生成一些东西。我创建了一个可以生成多个文件的工作解决方案。到目前为止,我很自豪:)

但现在我想启用为某些项目文件夹生成文件。我已经尝试了一些基于谷歌的东西,但似乎它们都使用特殊/其他 T4 解决方案。所以我的问题是有没有一种方法可以(相对容易地)将多个文件生成到单独的文件夹中(比如说;“存储过程”中的 2 个文件和“表”中的 2 个不同文件)?

我现在拥有的是基于https://github.com/renegadexx/T4.Helper/blob/master/Source/TemplateFilemanager.CS.ttinclude

我制作的是这样的:

<#@ include file="TemplateFileManagerV2.1.ttinclude" #>
    
<#

    string connectionString = "......."; 
    SqlConnection conn = new SqlConnection(connectionString); 
    string selectQueryTables = "MyQueryForTables"; 
    SqlDataAdapter commandTables = new SqlDataAdapter(selectQueryTables,conn); 

    DataSet TablestoGenerate = new DataSet();
    commandTables.Fill(TablestoGenerate, "Tables");
    var manager = TemplateFileManager.Create(this);

    foreach (DataRow tRow in TablestoGenerate.Tables["Tables"].Rows)  
      
            string FileName = tRow["TableType"].ToString().Trim(' ')+'.'+tRow["TableName"].ToString().Trim(' ')+".sql";
            manager.StartNewFile(FileName);
#>
            CREATE TABLE [<#= tRow["TableType"].ToString().Trim(' ') #>].[<#= tRow["TableName"].ToString().Trim(' ')#>] (
            <#
                string selectQueryColumns = "MyQueryForColumns";
                SqlDataAdapter commandColumns = new SqlDataAdapter(selectQueryColumns,conn); 
                DataSet ColumnstoGenerate = new DataSet();    
                commandColumns.Fill(ColumnstoGenerate, "Columns");

                foreach (DataRow cRow in ColumnstoGenerate.Tables["Columns"].Rows)
                
            #>
                    , [<#= cRow["ColumnName"].ToString().Trim(' ') #>] [<#= cRow["DataType"].ToString().Trim(' ') #>]<# if(cRow["precision"] != DBNull.Value)  #>(<#= cRow["precision"].ToString().Trim(' ') #>)<#  #>

            <#
                
            #>
            )
        GO
    <#
       

    manager.Process();

#>

【问题讨论】:

如果您不想使用 T4 管理器,也可以通过 T4 模板中的几行代码来实现:tim-maes.com/2019/08/12/… 那为什么会更好? 【参考方案1】:

您可以使用 EnvDTE.ProjectItems.AddFromFile() 方法将现有文件添加到 VS 项目 - 接口文档here。

我扩展了 Damian Guard here 创建的超棒工具,他在其中从单个 T4 模板创建多个文件,以允许还可以选择指定将这些文件放入文件夹中。代码相当简单,不依赖外部工具/包。

这会在每个单独的文件夹中为您提供一个单独的文件

tt 文件是这样的

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="EnvDTE"#>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic"#>
<#@ import namespace="System.Linq"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
<#@ output extension="/" #>
<#@ template language="C#v3.5" hostspecific="True"#>
<#@ include file="Manager.ttinclude"#>

<#
    var manager = new Manager(Host, GenerationEnvironment, true, "T4CustomFileGeneration")
    
        OutputPath = Path.GetDirectoryName(Host.TemplateFile),
    ;
#>

<# manager.StartBlock("FooStoredProc.sql", "Stored Procedures"); #>
CREATE PROC FOO ...
<# manager.EndBlock(); #>

<# manager.StartBlock("BarTable.sql", "Tables"); #>
SELECT * FROM Bar ...
<# manager.EndBlock(); #>

<# manager.Process(); #>

主要逻辑在 ttinclude 中,为简洁起见,我已在下面链接到该 ttinclude。但是你应该不需要在 ttinclude 中修改任何内容,只需在 tt 文件中指定你想要的文件、文件夹和 SQL 逻辑即可。

Working Demo Here

【讨论】:

是的,这很棒。它在演示中效果很好,现在我将尝试在我的项目中使用它。我也可以制作子文件夹吗? 我已经尝试了几个晚上来让它工作。但这让我很沮丧。我的主要问题是:1)我尝试将我的解决方案与工作演示结合起来。但是当我添加我的 SQL 连接部分时,我收到如下错误: 编译转换:找不到类型或命名空间名称“SqlConnection”(您是否缺少 using 指令或程序集引用?) T4CustomFileGeneration 我尝试添加 NuGet System。 Data.SqlClient 但这并没有解决任何问题 2)我有一个生成器项目和一个数据库项目。生成器确实在另一个项目中创建了 .sql 文件。我怎样才能做到这一点? @MiKeZZa 您可以将您拥有的内容推送到该存储库中的分支吗?我去看看,看看能不能帮到你。 我不知道该怎么做。我可以在github.com/DanielGasson/t4-examples 上提出问题,但似乎不可能创建分支。还是说我是个 n00b,以至于我什至错过了一些东西?

以上是关于T4 TemplateFileManager 输出到项目文件夹的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 4.1 T4 输出到 IDbset

2015_B t4格子中输出

当我们需要生成模板输出工件时,我们如何用 Roslyn 替换 T4

套题T4

2015_B t4格子中输出

在 Visual Studio Code 中执行 T4 文本模板