C#ORM学习笔记:T4⼊门及⽣成数据库实体类⼀、什么是T4?
1.1、T4简介
T4,即4个T开头的英⽂字母组合:Text Template Transformation Toolkit,是微软官⽅在Visual Studio 2008开始使⽤的代码⽣成引擎。T4是由⼀些⽂本块和控制逻辑组成的混合模板,简单地说,T4可以根据模板⽣成您想要的⽂件,如类⽂件、⽂本⽂件、HTML等等。
VS提供了⼀套基于T4引擎的代码⽣成执⾏环境,由以下程序集构成:
Microsoft.VisualStudio.TextTemplating.10.0.dll
Microsoft.VisualStudio.TextTemplating.Interfaces.10.0.dll
Microsoft.VisualStudio.TextTemplating.Modeling.10.0.dll
Microsoft.VisualStudio.TextTemplating.VSHost.10.0.dll
1.2、T4模板类型
T4模板有两种类型:
1)运⾏时模板
在应⽤程序中执⾏运⾏时T4⽂本模板,以便⽣成⽂本字符串。
若要创建运⾏时模板,请向您的项⽬中添加"运⾏时⽂本模板"⽂件。另外,您还可以添加纯⽂本⽂件并将其"⾃定义⼯具"属性设置为"TextTemplatingFilePreprocessor"。
2)设计时模板
在VS中执⾏设计时T4⽂本模板,以便定义应⽤程序的部分源代码和其它资源。
若要创建设计时模板,请向您的项⽬中添加"⽂本模板"⽂件。另外,您还可以添加纯⽂本⽂件并将其"⾃定义⼯具"属性设置为"TextTemplatingFileGenerator"。
1.3、插件安装
VS默认的编辑⼯具⽆⾼亮、⽆提⽰,错误不容易定位,建议安装插件进⾏编写T4代码。
⼆、T4 Hello World⽰例
假设有⼀个控制台应⽤程序LinkTo.Test.ConsoleT4,现在要输出"Hello World"字符串,Program代码
如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinkTo.Test.ConsoleT4
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
Console.Read();
}
}
}
现在把Program.cs⽂件删除掉,利⽤T4模板⽣成⼀个与上述代码相同的Program.cs,操作⽅法如下:
1)项⽬右键"添加"->"新建项"->"⽂本模板",将名称更改为。
2)的代码如下:
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
<#
string ClassName = "Program";
#>
namespace LinkTo.Test.ConsoleT4
{
自动打卡软件appclass <#=ClassName #>
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
Console.Read();
}
}
}
3)点击保存,即可看到下⽣成了⼀个Program.cs⽂件,代码与最初的Hello World⼀样。
三、T4 Hello World⽰例扩展
现在扩展⼀下Hello World⽰例,在程序中增加两个类:
1)Hello类,输出"Hello"。
2)World类,输出"World"。
代码如下:
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
<#
string ClassName = "Program";
#>
<#
List<string> classNames = new List<string>() {"Hello","World"};
List<string> callMethods = new List<string>();吕氏春秋值得看吗
#>
namespace LinkTo.Test.ConsoleT4
{
<#
foreach (string className in classNames)
{
callMethods.Add($"{className}.Show();");
#>
class <#=className #>
{
///<summary>
///<#=className #>类Show()⽅法
///</summary>
public static void Show()
{
Console.WriteLine("<#=className #>");
}
}
<#
}
#>
class <#=ClassName #>
mysqlschema作用{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
<#
foreach (string callMethod in callMethods)
{
#>
//<#=callMethod #>⽅法调⽤
<#=callMethod #>
<#
}
#>
Console.Read();
}
}
}
<
eor是什么意思啊⽣成⽂件如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LinkTo.Test.ConsoleT4
{
class Hello
{
///<summary>
/// Hello类Show()⽅法
///</summary>
public static void Show()
侧边栏怎么移动{
Console.WriteLine("Hello");
}
}
go和java哪个简单class World
{
///<summary>
/// World类Show()⽅法
///</summary>
public static void Show()
{
Console.WriteLine("World");
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
//Hello.Show();⽅法调⽤
Hello.Show();
//World.Show();⽅法调⽤
World.Show();
Console.Read();
}
}
}
Program.cs
四、T4模板的基本结构
代码块可分为两种:⽂本及程序脚本。
4.1、⽂本:就是需要⽣成的⽂本
4.2、程序脚本:内部执⾏,最终⽣成想要的⽂本。T4中<# #>中的部分,都属于程序脚本内容。
为了⽅便理解,使⽤"块"(Block)来细分语法。块是构成T4模板的基本单元,可以分成5类:指令块(Directive Block)、⽂本块(Text Block)、代码语句块(Statement Block)、表达式块(Expression Block)、类特性块(Class Feature Block)。
4.2.1、指令块(Directive Block)
和ASP.NET页⾯的指令⼀样,它们出现在⽂件头,通过<#@ … #>表⽰。其中<#@ template … #>指令是必须的,⽤于定义模板的基本属性,⽐如编程语⾔、基于的⽂化、是否⽀持调式等。
指令通常是模板⽂件或包含的⽂件中的第⼀个元素。不应将它们放置在代码块<#...#>内,也不应放置在类功能块<#+...#>之后。
T4 模板指令
<#@ template [language="C#"] [hostspecific="true"] [debug="true"] [inherits="templateBaseClass"] [culture="code"] [compilerOptions="options"] #>
T4 参数指令
<#@ parameter type="Full.TypeName" name="ParameterName" #>
T4 输出指令
<#@ output extension=".fileNameExtension" [encoding="encoding"] #>
T4 程序集指令
<#@ assembly name="[assembly strong name|assembly file name]" #>
$(SolutionDir):当前项⽬所在解决⽅案⽬录
$(ProjectDir):当前项⽬所在⽬录
$(TargetPath):当前项⽬编译输出⽂件绝对路径
$(TargetDir):当前项⽬编译输出⽬录
T4 导⼊指令
<#@ import namespace="namespace" #>
T4 包含指令
<#@ include file="filePath" #>
4.2.2、⽂本块(Text Block)
⽂本块就是直接原样输出的静态⽂本,不需要添加任何的标签。
4.2.3、代码语句块(Statement Block)
代码语句块通过<# Statement #>的形式表⽰,中间是⼀段通过相应编程语⾔编写的程序调⽤,我们可以通过代码语句快控制⽂本转化的流程。
4.2.4、表达式块(Expression Block)
表达式块以<#=Expression #>的形式表⽰,通过它可以动态地解析字符串表达式内嵌到输出的⽂本中。
4.2.5、类特性块(Class Feature Block)
如果⽂本转化需要⼀些⽐较复杂的逻辑,代码可能需要写在⼀个单独的辅助⽅法中,甚⾄是定义⼀些单独的类。类特性块的表现形式为<#+ FeatureCode #>。
五、T4模板⽣成数据库实体类
5.1、添加⼀个T4Code⽂件夹,并在下⾯新建两个⽂本模板,需要注意的是,这⾥不使⽤默认的.tt扩展名,⽽是.ttinclude,将它们作为包含⽂件使⽤。
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="$(ProjectDir)\Lib\MySql.Data.Dll" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data"#>
<#@ import namespace="System.Data.SqlClient"#>
<#@ import namespace="MySql.Data.MySqlClient"#>
<#+
#region T4Code
///<summary>
///数据库架构接⼝
///</summary>
public interface IDBSchema : IDisposable
{
List<string> GetTableList();
Table GetTableMetadata(string tableName);
}
///<summary>
///数据库架构⼯⼚
///</summary>
public class DBSchemaFactory
{
static readonly string DatabaseType = "SqlServer";
public static IDBSchema GetDBSchema()
{
IDBSchema dbSchema;
switch (DatabaseType)
{
case"SqlServer":
{
dbSchema =new SqlServerSchema();
break;
}
case"MySql":
{
dbSchema = new MySqlSchema();
break;
}
default:
{
throw new ArgumentException("The input argument of DatabaseType is invalid."); }
}
return dbSchema;
}
}
/
//<summary>
/// SqlServer
///</summary>
public class SqlServerSchema : IDBSchema
{
public string ConnectionString = "Server=.;Database=CFDEV;Uid=sa;Pwd=********;";
public SqlConnection conn;
public SqlServerSchema()
{
conn = new SqlConnection(ConnectionString);
conn.Open();
}
public List<string> GetTableList()
{
DataTable dt = conn.GetSchema("Tables");
List<string> list = new List<string>();
foreach (DataRow row in dt.Rows)
{
list.Add(row["TABLE_NAME"].ToString());
}
return list;
}
public Table GetTableMetadata(string tableName)
{
string commandText = string.Format("SELECT * FROM {0}", tableName); ;
SqlCommand cmd = new SqlCommand(commandText, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.FillSchema(ds, SchemaType.Mapped, tableName);
Table table = new Table(ds.Tables[0]);
return table;
}
public void Dispose()
{
if (conn != null)
{
conn.Close();
}
}
}
///<summary>
/// MySql
///</summary>
public class MySqlSchema : IDBSchema
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论