欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

c# 使用T4模板生成实体类(sqlserver)

程序员文章站 2022-07-02 13:26:07
新建类库,右键添加 "文本模板" 添加完成之后生成如下后缀为 tt的文件: 双击文件:TextTemplate_Test.tt 文件打开,替换代码如下 需要更换几个配置的地方: 1,设置数据库连接,找到该段代码:string connectionString ="Data Source=127.0. ......

新建类库,右键添加 "文本模板"

c# 使用T4模板生成实体类(sqlserver)

添加完成之后生成如下后缀为 tt的文件:

c# 使用T4模板生成实体类(sqlserver)

 

 双击文件:texttemplate_test.tt 文件打开,替换代码如下

 1 <#@ template debug="false" hostspecific="true" language="c#" #>
 2 <#@ assembly name="system.core" #>
 3 <#@ assembly name="system.data" #>
 4 <#@ assembly name="system.xml" #>
 5 <#@ import namespace="system.linq" #>
 6 <#@ import namespace="system.text" #>
 7 <#@ import namespace="system.collections.generic" #>
 8 <#@ import namespace="system.data.sqlclient" #>
 9 <#@ import namespace="system.data" #>
10 <#@ include file="modelauto.ttinclude"#>
11 <#@ output extension=".cs" #>
12 
13 <# var manager = new manager(host, generationenvironment, true) { outputpath = path.getdirectoryname(host.templatefile)}; #>
14 <# 
15     //数据库连接
16     string connectionstring ="data source=127.0.0.1;initial catalog=testdb;user id=sa;password=123456;"; 
17     sqlconnection conn = new sqlconnection(connectionstring); 
18     conn.open(); 
19     //查询表
20     system.data.datatable schema = conn.getschema("tables"); 
21     string selectquery = "select * from @tablename";   //查询表语句
22     sqlcommand command = new sqlcommand(selectquery,conn); 
23     sqldataadapter ad = new sqldataadapter(command); 
24     system.data.dataset ds = new dataset();
25     //查询字段
26     string propquery = "select 表名=sobj.name,字段名=scol.name,字段说明=sprop.[value] from syscolumns as scol inner join sys.sysobjects as sobj on scol.id=sobj.id and sobj.xtype='u' and sobj.name<>'dtproperties' left join sys.extended_properties as sprop on scol.id=sprop.major_id and scol.colid=sprop.minor_id where sobj.name='@tablename' and scol.name='@columnname'"; 
27     sqlcommand command2 = new sqlcommand(propquery,conn); 
28     sqldataadapter ad2 = new sqldataadapter(command2); 
29     system.data.dataset ds2 = new dataset();
30  #>
31 
32 <# foreach(system.data.datarow row in schema.rows) { #>
33 <# manager.startblock(row["table_name"].tostring()+".cs"); #>
34 using system;
35 
36 namespace entity.model
37 {
38     /// <summary>
39     /// 实体类:<#= row["table_name"].tostring() #> 
40     /// </summary>
41     [serializable]
42     public class <#= row["table_name"].tostring() #>
43     {
44         <# 
45         ds.tables.clear();
46         command.commandtext = selectquery.replace("@tablename","["+row["table_name"].tostring()+"]"); 
47         ad.fillschema(ds, schematype.mapped, row["table_name"].tostring());
48         foreach (datacolumn dc in ds.tables[0].columns)
49         { 
50         #>
51             <# 
52             ds2.tables.clear();
53             command2.commandtext = propquery.replace("@tablename",row["table_name"].tostring()); 
54             command2.commandtext = command2.commandtext.replace("@columnname",dc.columnname); 
55             ad2.fill(ds2);
56             #>
57 
58         ///<summary>
59         ///<#= manager.transfromsqltype(dc.datatype.name) #>:<#=ds2.tables[0].rows[0].itemarray[2]#>
60         ///</summary>
61         public <#= manager.transfromsqltype(dc.datatype.name) #> <#= dc.columnname #> { get; set; }  
62         <#}#>    
63     }
64 }
65 
66 <# manager.endblock(); #>
67 
68 <#}#>
69 
70 <#manager.process(true);#>

需要更换几个配置的地方:

1,设置数据库连接,找到该段代码:string connectionstring ="data source=127.0.0.1;initial catalog=testdb;user id=sa;password=123456;";  替换你要连接的数据库即可;

2,设置命名空间,找到代码:namespace entity.model {....} ,将该处的命名空间替换你要的即可;

3,相同目录下添加代码自动生成逻辑文件,文件名字为:modelauto.ttinclude

文件内容如下,

  1 <#@ assembly name="system.core"#>
  2 <#@ assembly name="envdte"#>
  3 <#@ import namespace="system.collections.generic"#>
  4 <#@ import namespace="system.io"#>
  5 <#@ import namespace="system.text"#>
  6 <#@ import namespace="microsoft.visualstudio.texttemplating"#>
  7 
  8 <#+
  9 
 10 class manager
 11 {
 12     public struct block {
 13         public string name;
 14         public int start, length;
 15     }
 16 
 17     public list<block> blocks = new list<block>();
 18     public block currentblock;
 19     public block footerblock = new block();
 20     public block headerblock = new block();
 21     public itexttemplatingenginehost host;
 22     public managementstrategy strategy;
 23     public stringbuilder template;
 24     public string outputpath { get; set; }
 25 
 26     public manager(itexttemplatingenginehost host, stringbuilder template, bool commonheader) {
 27         this.host = host;
 28         this.template = template;
 29         outputpath = string.empty;
 30         strategy = managementstrategy.create(host);
 31     }
 32 
 33     public void startblock(string name) {
 34         currentblock = new block { name = name, start = template.length };
 35     }
 36 
 37     public void startfooter() {
 38         footerblock.start = template.length;
 39     }
 40 
 41     public void endfooter() {
 42         footerblock.length = template.length - footerblock.start;
 43     }
 44 
 45     public void startheader() {
 46         headerblock.start = template.length;
 47     }
 48 
 49     public void endheader() {
 50         headerblock.length = template.length - headerblock.start;
 51     }    
 52 
 53     public void endblock() {
 54         currentblock.length = template.length - currentblock.start;
 55         blocks.add(currentblock);
 56     }
 57 
 58     public void process(bool split) {
 59         string header = template.tostring(headerblock.start, headerblock.length);
 60         string footer = template.tostring(footerblock.start, footerblock.length);
 61         blocks.reverse();
 62         foreach(block block in blocks) {
 63             string filename = path.combine(outputpath, block.name);
 64             if (split) {
 65                 string content = header + template.tostring(block.start, block.length) + footer;
 66                 strategy.createfile(filename, content);
 67                 template.remove(block.start, block.length);
 68             } else {
 69                 strategy.deletefile(filename);
 70             }
 71         }
 72     }
 73 
 74         /// <summary>
 75         /// sql[不完善,需要的自己改造]
 76         /// 更换字段类型
 77         /// </summary>
 78         /// <param name="type"></param>
 79         /// <returns></returns>
 80         public string transfromsqltype(string type)
 81         {
 82             if (string.isnullorempty(type))
 83             {
 84                 return string.empty;
 85             }
 86             if (string.equals(type, "boolean", stringcomparison.ordinalignorecase))
 87             {
 88                 return "bool";
 89             }
 90             else if (string.equals(type, "int32", stringcomparison.ordinalignorecase))
 91             {
 92                 return "int";
 93             }
 94             else if (string.equals(type, "int64", stringcomparison.ordinalignorecase))
 95             {
 96                 return "long";
 97             }
 98             else if (string.equals(type, "string", stringcomparison.ordinalignorecase))
 99             {
100                 return "string";
101             }
102             else if(string.equals(type, "byte", stringcomparison.ordinalignorecase))
103             {
104                 return "byte";
105             }
106             else if (string.equals(type, "decimal", stringcomparison.ordinalignorecase))
107             {
108                 return "decimal";
109             }
110             else if (string.equals(type, "datetime", stringcomparison.ordinalignorecase))
111             {
112                 return "datetime";
113             }
114             return "string";
115         }
116 
117 }
118 
119 class managementstrategy
120 {
121     internal static managementstrategy create(itexttemplatingenginehost host) {
122         return (host is iserviceprovider) ? new vsmanagementstrategy(host) : new managementstrategy(host);
123     }
124 
125     internal managementstrategy(itexttemplatingenginehost host) { }
126 
127     internal virtual void createfile(string filename, string content) {
128         file.writealltext(filename, content);
129     }
130 
131     internal virtual void deletefile(string filename) {
132         if (file.exists(filename))
133             file.delete(filename);
134     }
135 }
136 
137 class vsmanagementstrategy : managementstrategy
138 {
139     private envdte.projectitem templateprojectitem;
140 
141     internal vsmanagementstrategy(itexttemplatingenginehost host) : base(host) {
142         iserviceprovider hostserviceprovider = (iserviceprovider)host;
143         if (hostserviceprovider == null)
144             throw new argumentnullexception("could not obtain hostserviceprovider");
145 
146         envdte.dte dte = (envdte.dte)hostserviceprovider.getservice(typeof(envdte.dte));
147         if (dte == null)
148             throw new argumentnullexception("could not obtain dte from host");
149 
150         templateprojectitem = dte.solution.findprojectitem(host.templatefile);
151     }
152 
153     internal override void createfile(string filename, string content) {
154         base.createfile(filename, content);
155         ((eventhandler)delegate { templateprojectitem.projectitems.addfromfile(filename); }).begininvoke(null, null, null, null);
156     }
157 
158     internal override void deletefile(string filename) {
159         ((eventhandler)delegate { findanddeletefile(filename); }).begininvoke(null, null, null, null);
160     }
161 
162     private void findanddeletefile(string filename) {
163         foreach(envdte.projectitem projectitem in templateprojectitem.projectitems) {
164             if (projectitem.get_filenames(0) == filename) {
165                 projectitem.delete();
166                 return;
167             }
168         }
169     }
170 }#>

接下来就是见证奇迹的时刻,选中 texttemplate_test.tt 文件 按 ctrl+c即可(每次更新实体类时,需要先修改一下模板文件,随便修改什么地方,按个空格也可以),生成模板代码如下:

c# 使用T4模板生成实体类(sqlserver)

 

 c# 使用T4模板生成实体类(sqlserver)