惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

博客园 - james.dong

加快大表关联查询的速度(oracle) DataTable 排序 - james.dong - 博客园 查询oracle数据库中所有视图和表的信息 日期验证正规表达式( YYYY-MM-DD YYYY-MM-DD hh:mm:ss YYYY/MM/DD) windows2000server下 iis 无法下载 .exe , .dll文件的解决办法。 - james.dong C#中datagridview使用技巧系列谈(-)让输入焦点从左到右收藏 oracle中创建自增字段 .net 序列化和反序列化自定义treenode类 LotusScript基础知识(二) LotusScript基本语法知识(一) LotusScript中Option 的含义 Lotusscript中Instr()函数的功能和用法 System.Xml.XmlDocument.SelectNodes() 查询不到节点问题? - james.dong - 博客园 Combox控件实现类似TextBox控件的ReadOnly=true时的背景颜色和字体颜色!(WinForm) WPF 中的 BitmapEffect 的 各种样式 WPF相关文章汇总 使用List泛型,怎么排序 asp.net2.0解决用户控件图片相对路径出错的问题,ResolveUrl的用法 window.showModalDialog()时没有显示修改后的数据 - james.dong - 博客园
初次使用T4引擎生成数据库表实体 - james.dong - 博客园
james.dong · 2010-10-25 · via 博客园 - james.dong

网上看到有人使用T4来生成代码,发现这个东西自己没有接触过,因此google了一下,学习了一下相关的知识。

 现把自己学习的过程记录一下:

下面的代码主要是通过T4模板生成数据库表实体对象的过程。

1、首先我们需要实现 ITextTemplatingEngineHost 接口的类。该类存在"Microsoft.VisualStudio.TextTemplating.dll"中,因此我们需要在项目工程中引用此Dll文件。

下面是代码:

代码

 [Serializable]
    
public class TableHost : Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost {
        
private string _namespace = "JXDModel";
        
        
public string Namespace {
            
get { return _namespace; }
            
set { _namespace = value; }
        }
protected string _classname = "tablename";
        
public string Classname {
            
get { return _classname; }
            
set { _classname = value; }
        }
        
protected DataTable _dt = new DataTable();
        
public DataTable Dt {
            
get { return _dt; }
            
set { _dt = value; }
        }
protected string _templateFile = "";
        
public string TemplateFile {
            
get { return _templateFile; }
            
set { _templateFile = value; }
        }
        
protected string _fileExtension = ".cs";
        
public string FileExtension {
            
get { return _fileExtension; }
            
set { _fileExtension = value; }
        }
        
public IList<string> StandardAssemblyReferences {
            
get {
                
return new string[]
            {
                
typeof(System.Uri).Assembly.Location,
                
typeof(TableHost).Assembly.Location,
                
typeof(DbType).Assembly.Location,
                
typeof(XmlDataDocument).Assembly.Location,
                
typeof(System.Xml.Serialization.XmlSchemas).Assembly.Location,
                
typeof(System.AppDomain ).Assembly.Location 
            };
            }
        }
        
public IList<string> StandardImports {
            
get {
                
return new string[]
        { 
            
"System",
            
"System.Data",
            
"System.IO",
            
"System.Xml",
            
"System.Xml.Serialization",
            
"System.Text",
            
"windows2008",
            
"System.Data.Common",
            
"System.Collections",
            
"System.Collections.Generic",
            
"System.Collections.Specialized"
        };
            }
        }
public object GetHostOption(string optionName) {
            
object returnObject;
            
switch (optionName) {
                
case "CacheAssemblies":
                    returnObject 
= true;
                    
break;
                
default:
                    returnObject 
= null;
                    
break;
            }
            
return returnObject;
        }
public void SetFileExtension(string extension) {
            _fileExtension 
= extension;
        }
private System.Text.Encoding _fileEncodingValue = System.Text.Encoding.UTF8;
        
public void SetOutputEncoding(System.Text.Encoding encoding, bool fromOutputDirective) {
            _fileEncodingValue 
= encoding;
        }
private CompilerErrorCollection _errorsValue;
        
public CompilerErrorCollection Errors {
            
get { return _errorsValue; }
        }
public void LogErrors(CompilerErrorCollection errors) {
            _errorsValue 
= errors;
        }
        
public string ResolvePath(string fileName) {
            
return fileName;
        }
        
public bool LoadIncludeText(string requestFileName, out string content, out string location) {
            content 
= System.String.Empty;
            location 
= System.String.Empty;//If the argument is the fully qualified path of an existing file,
            
//then we are done.
            
//----------------------------------------------------------------
            if (File.Exists(requestFileName)) {
                content 
= File.ReadAllText(requestFileName);
                
return true;
            }
//This can be customized to search specific paths for the file.
                
//This can be customized to accept paths to search as command line
                
//arguments.
                
//----------------------------------------------------------------
            else {
                
return false;
            }
        }
        
public string ResolveAssemblyReference(string assemblyReference) {
            
if (File.Exists(assemblyReference)) {
                
return assemblyReference;
            }
            
string candidate = Path.Combine(Path.GetDirectoryName(this.TemplateFile), assemblyReference);
            
if (File.Exists(candidate)) {
                
return candidate;
            }
            
return "";
        }
        
public Type ResolveDirectiveProcessor(string processorName) {
            
throw new Exception("Directive Processor not found");
        }
public string ResolveParameterValue(string directiveId, string processorName, string parameterName) {
            
if (directiveId == null) {
                
throw new ArgumentNullException("the directiveId cannot be null");
            }
            
if (processorName == null) {
                
throw new ArgumentNullException("the processorName cannot be null");
            }
            
if (parameterName == null) {
                
throw new ArgumentNullException("the parameterName cannot be null");
            }
//Code to provide "hard-coded" parameter values goes here.
            
//This code depends on the directive processors this host will interact with.//If we cannot do better, return the empty string.
            return String.Empty;
        }
        
public AppDomain ProvideTemplatingAppDomain(string content) {
            
//This host will provide a new application domain each time the 
            
//engine processes a text template.
            
//-------------------------------------------------------------
            return AppDomain.CreateDomain("Generation App Domain");//This could be changed to return the current appdomain, but new 
            
//assemblies are loaded into this AppDomain on a regular basis.
            
//If the AppDomain lasts too long, it will grow indefintely, 
            
//which might be regarded as a leak.//This could be customized to cache the application domain for 
            
//a certain number of text template generations (for example, 10).//This could be customized based on the contents of the text 
            
//template, which are provided as a parameter for that purpose.
        }
    }

 下载代码实例: /Files/james-dong/T42008.rar

2、编写生成对象实体的模板文件(.tt) 

代码

<#@ Template language="C#" debug="true" hostspecific="true" #>
<#@ Assembly name = "System.Data" #>
<#@ Assembly name = "System.Xml" #>
<#@ import Namespace = "System.Data" #>
<#@ import Namespace = "System.Data.SqlClient" #>
<#@ import Namespace = "System.Xml" #>
<#@ output extension= ".cs" #>using System;
using system.Data;<#
  TableHost host 
= (TableHost)(Host);
  
string namespacess = host.Namespace;
  
string classname = host.Classname;
  DataTable dt 
= host.Dt;
#
>namespace <#=namespacess #>
{
    
public class <#= classname #>
    {
      
<#
        
foreach( DataColumn dc in dt.Columns )
        {
      #
>
          
private <#= dc.DataType.Name.ToString().ToLower() #> _<#= dc.ColumnName.ToString().ToLower() #>;
          
public <#= dc.DataType.Name.ToString().ToLower() #> <#= dc.ColumnName.ToString().ToUpper() #>
          {
            
getreturn _<#= dc.ColumnName.ToString().ToLower()#>; }
            
set{ _<#=dc.ColumnName.ToString().ToLower()#>= value; }
          }
      
<#  
        }
      #
>
    }    
}

3、调用T4引擎生成实体过程

代码

public void Process(string namespace , string classname , string templatefile , string connstring ) {
            TableHost host 
= new TableHost();
            host.Namespace 
= namespace ;
            host.Classname 
= classname ;
            host.FileExtension 
= ".cs";
            host.TemplateFile 
= templatefile;                    

            SqlConnection conn 

= new SqlConnection(constring);
            conn.Open();
            DataTable dt 
= conn.GetSchema("tables");            
            
string sql = "select * from " + host.Classname;
            SqlCommand cmd 
= new SqlCommand(sql, conn);
            SqlDataAdapter ad 
= new SqlDataAdapter(cmd);
            DataSet ds 
= new DataSet();
            ad.FillSchema(ds, SchemaType.Mapped, host.Classname );
            host.Dt 
= ds.Tables[0];

            Microsoft.VisualStudio.TextTemplating.Engine engine 

= new Microsoft.VisualStudio.TextTemplating.Engine();
            
string input = "";
            
string output = "";
            input 
= System.IO.File.ReadAllText(host.TemplateFile);
            output 
= engine.ProcessTemplate(input, host);string outputname = host.Classname + host.FileExtension;

            System.IO.File.WriteAllText(outputname  , output);

foreach (CompilerError error in host.Errors) {
                textBox1.Text 
+= error.ToString();
            }

到此,一个简单的数据库表实体类的功能就实现了。