如何使T4文本模板数据库驱动

Posted

技术标签:

【中文标题】如何使T4文本模板数据库驱动【英文标题】:how to make T4 text template database driven 【发布时间】:2018-10-18 02:23:36 【问题描述】:

我正在尝试使用代码生成 atm,我已经编写了一个小模板来完成我需要它做的事情,但是我需要自己对属性进行硬编码,我想从表中的数据库中提取类和属性名称是类,索引字段是属性。想法是写一个基于表索引的过滤器类。我现在拥有的代码假定我有 1 个表和 3 个字段用作过滤条件。 目前没有任何代码来生成编译版本,因为 VS 在内部执行此操作。 这是我到目前为止所拥有的:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="namespacename" type="System.String" #>
<#@ parameter name="filterobjectname" type="System.String" #>
<#@ parameter name="property1" type="System.String" #>
<#@ parameter name="property2" type="System.String" #>
<#@ parameter name="property3" type="System.String" #>

<#@ output extension=".cs" #>
using AzzWork.Business;
using Ventura.Business.Entities;
<# string _namespacename; if(this.namespacename==null)_namespacename = "Ventura.Business";else_namespacename = this.namespacename; #>
<# string _classname; if(this.filterobjectname==null)_classname = "BusinessObject";else_classname = this.filterobjectname;#>
<# string _property1; if(this.property1==null)_property1 = "LastName";else_property1 = property1;#>
<# string _property1c = _property1.Substring(0, 1).ToLower() + _property1.Substring(1);#>
<# string _property2; if(this.property2==null)_property2 = "Email";else_property2 = property2;#>
<# string _property2c = _property2.Substring(0, 1).ToLower() + _property2.Substring(1);#>
<# string _property3; if(this.property3==null)_property3 = "FirstName";else_property3 = property3;#>
<# string _property3c = _property3.Substring(0, 1).ToLower() + _property3.Substring(1);#>
<# string seperator1; if((_property1!=null && _property2!=null) || (_property1!=null && _property2==null && _property3!=null))seperator1=", ";elseseperator1="";#>
<# string seperator2; if(_property2!=null && _property3!=null)seperator2=", ";elseseperator2=""; #>
namespace <#= _namespacename #>

    public static class <#= _classname #>FilterFactory
        internal static AzzFilterCollection<<#= _classname #>> GetFilterFor<#= _classname #>(<#if(_property1!=null)#>string <#=_property1c #>Part<##><#=seperator1#><#if(_property2!=null)#>string <#=_property2c #>Part<##><#=seperator2#><#if(_property3!=null)#>string <#=_property3c #>Part<##>)
        => new AzzFilterCollection<<#=_classname#>>()
<#if(_property1!=null) #>
            .AddFilterFor<#= _property1 #>(<#=_property1c #>Part)
<##>
<#if(_property2!=null) #>
            .AddFilterFor<#= _property2 #>(<#=_property2c #>Part)
<##>
<#if(_property3!=null) #>
            .AddFilterFor<#= _property3 #>(<#=_property3c #>Part)<##>;
        <#if (_property1!=null)#>
internal static AzzFilterCollection<<#=_classname #>> AddFilterFor<#= _property1 #>(this AzzFilterCollection<<#= _classname#>> filterCollection, string <#= _property1c #>Part)
        
            if (<#= _property1c #>Part == null)
                return filterCollection;
            var filter = new AzzFilter<<#=_classname#>>(<#=_classname#>.ColumnNames.<#=_property1#>, <#=_property1c#>Part);
            return filterCollection.AddFilter(filter);
        
        <##>
<#if (_property2!=null)#>internal static AzzFilterCollection<<#=_classname #>> AddFilterFor<#= _property2 #>(this AzzFilterCollection<<#= _classname#>> filterCollection, string <#= _property2c #>Part)
        
            if (<#= _property2c #>Part == null)
                return filterCollection;
            var filter = new AzzFilter<<#=_classname#>>(<#=_classname#>.ColumnNames.<#=_property2#>, <#=_property2c#>Part);
            return filterCollection.AddFilter(filter);
        
        <##>
<#if (_property3!=null)#>
internal static AzzFilterCollection<<#=_classname #>> AddFilterFor<#= _property3 #>(this AzzFilterCollection<<#= _classname#>> filterCollection, string <#= _property3c #>Part)
        
            if (<#= _property3c #>Part == null)
                return filterCollection;
            var filter = new AzzFilter<<#=_classname#>>(<#=_classname#>.ColumnNames.<#=_property3#>, <#=_property3c#>Part);
            return filterCollection.AddFilter(filter);
        
        <##>
    

【问题讨论】:

您遇到了什么问题?由于您可以在 T4 生成中运行任何 C# 代码,因此您还可以运行关闭并查询数据库以获取元数据的代码(尽管,公平警告,如果您的数据库发生更改,这不会重新生成,并将其集成到自动构建有其自身的问题)。只需编写代码以输出 C#,就好像您不在 T4 模板中一样,除了您使用 &lt;# #&gt; 而不是编写 Console.WriteLine 【参考方案1】:

我猜你正在为 SQL 寻找一些东西。

这对你有帮助吗?

This,This (same),

还有this

【讨论】:

t4-editor.tangible-engineering.com/… 正是我所需要的,谢谢。 @NicoHaegens :)

以上是关于如何使T4文本模板数据库驱动的主要内容,如果未能解决你的问题,请参考以下文章

在 T4 文本模板中调用异步方法?

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

T4模板:T4模板之基础篇

T4模板:T4模板之菜鸟篇

T4模板使用

如何在构建时在 Blazor 项目中运行 T4 模板