c# 使用T4模板生成实体类(sqlserver)
程序员文章站
2022-03-25 18:49:43
新建类库,右键添加 "文本模板" 添加完成之后生成如下后缀为 tt的文件: 双击文件:TextTemplate_Test.tt 文件打开,替换代码如下 需要更换几个配置的地方: 1,设置数据库连接,找到该段代码:string connectionString ="Data Source=127.0. ......
新建类库,右键添加 "文本模板"
添加完成之后生成如下后缀为 tt的文件:
双击文件: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即可(每次更新实体类时,需要先修改一下模板文件,随便修改什么地方,按个空格也可以),生成模板代码如下:
上一篇: Python基础:异常处理