基于数据库的vs2019的T4模版代码⽣成器(⼀)基于sqlserver
数据库
总体介绍
参考⽂档:
只想⽤ 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、 include ⽂本⽂件代码
//引⼊命名空间
<#@ 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;
OutputPath = String.Empty;
strategy = ManagementStrategy.Create(host);
}
//开辟⼀个 block 块
public void StartBlock(String name) {
currentBlock = new Block { Name = name, Start = template.Length };
}
public void StartFooter() {
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 (_FileNames(0) == fileName) {
projectItem.Delete();
}
}
}
}#>
include⽂本⽂件
//引⼊命名空间
<#@ 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;
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 (_FileNames(0) == fileName) {
projectItem.Delete();
return;
}
}
}
}#>
6 模板⽂件
//如果要获取主机信息,记得把 hostspecific 设置成true
<#@ template debug="false" hostspecific="True" language="C#" #>
<#@ output extension=".cs" #>
//导⼊命名空间组件
<#@ assembly name="System.Data" #>
<#@ assembly name="l" #>
<#@ 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="$(include" #>
<#@ include file="$(include" #>
//定义我们的输出⽂件夹
<#
var OutputPath1 = Path.GetDirectoryName(Host.TemplateFile)+"\\work";
if (!Directory.Exists(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);
}
#>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论