Rare but practical codesmith skills

Source: Internet
Author: User

Codesmith, as a very useful code generation tool, has become a favorite of many programmers. In fact, many people only use it in manual introduction, here I will mainly introduce three useful but hard-to-find tips:

1. How to generate a batch of code files in batches based on the sub-template and store them in the specified folder.

The following is a template for generating data-layer code based on the table specified by the user. Save it as dataobjecttmp. CST (to reduce the amount of code, I only keep the insert function)

 <% @ Codetemplate Language = "C #" targetlanguage = "C #" DEBUG = "true" responseencoding = "UTF-8" Description = "" %> <br/> <% @ assembly name = "schemaexplorer" %> <br/> <% @ Assembly name = "system. data "%> <br/> <% @ Assembly name =" system. data. oracleclient "%> <br/> <% @ import namespace =" schemaexplorer "%> <br/> <% @ import namespace =" system. data "%> <br/> <% @ import namespace =" system. data. oracleclient "%> <br/> <% @ impo RT namespace = "system. collections. specialized "%> <br/> <% @ property name =" author "type =" string "Category =" context "default =" Wenliu "Optional =" true "Description =" author of this unit "%> <br/> <% @ property name =" datatable "type =" tableschema "Category =" context "Description =" table name in Database "%> </P> <p> <MCE: script runat = "template"> <! -- <Br/> Public String getdeletesql (tableschema datatable) <br/>{< br/> string strreturn = "delete from" + datatable. name; </P> <p> string strwhere = getprikeystring (datatable); <br/> If (strwhere. length> 0) <br/> strreturn + = "where" + strwhere; <br/> return strreturn; <br/>}</P> <p> Public String getprikeystring (tableschema datatable) <br/>{< br/> string strreturn = ""; <br/> If (datatable. hasprimarykey) <br/>{< br/> (INT I = 0; I <datatable. primarykey. membercolumns. count; I ++) <br/>{< br/> strreturn + = datatable. primarykey. membercolumns [I]. name + "=:" + datatable. primarykey. membercolumns [I]. name; <br/> if (I! = (Datatable. primarykey. membercolumns. count-1) <br/> strreturn + = "and"; <br/>}< br/> return strreturn; <br/>}</P> <p> Public String getsqltypeformdbtype (dbtype) <br/>{< br/> string strreturn = ""; <br/> switch (dbtype) <br/>{< br/> case dbtype. ansistring: <br/> case dbtype. ansistringfixedlength: <br/> case dbtype. string: <br/> case dbtype. stringfixedlength: <br/> strreturn = "varchar"; <br/> break; <Br/> case dbtype. boolean: <br/> strreturn = "false"; <br/> break; <br/> case dbtype. currency: <br/> case dbtype. decimal: <br/> case dbtype. double: <br/> strreturn = "float"; <br/> break; <br/> case dbtype. int16: <br/> case dbtype. int32: <br/> case dbtype. int64: <br/> strreturn = "int32"; <br/> break; <br/> case dbtype. datetime: <br/> strreturn = "datetime"; <br/> break; <br/> default: <br/> strreturn = "varchar"; <br/> Br Eak; <br/>}< br/> return strreturn; <br/>}</P> <p> Public String getclassname (INT iflag) <br/>{< br/> If (iflag = 0) <br/> return "module" + this. datatable. name. substring (1, 1 ). toupper () + this. datatable. name. substring (2); <br/> else if (iflag = 1) <br/> return "entity" + this. datatable. name. substring (1, 1 ). toupper () + this. datatable. name. substring (2); <br/> else <br/> return "entity" + this. datatable. name. substring (1, 1). Toupper () + this. datatable. name. substring (2); <br/>}</P> <p> Public void printheader () <br/>{< br/> response. writeline ("// ======================================== =========================== "); <br/> response. writeline ("// coded by: {0}", author); <br/> response. writeline ("// auto generated at: {0}", datetime. now); <br/> response. writeline ("// ======================================== =========================== "); <br/> res Ponse. writeline (); <br/>}</P> <p> // --> </MCE: SCRIPT> <br/> <% printheader (); %> <br/> using system; <br/> using system. data; <br/> using system. text; <br/> using system. data. oracleclient; </P> <p> namespace dataaccess <br/> {<br/> /// <summary> <br/> // the data module of <% = This. datatable. name %> <br/> /// </Summary> <br/> public class <% = getclassname (0) %> <br/>{< br/> Public <% = getclassname (0) %> () <br/> {<Br/>}< br/> # region field attribute </P> <p> <% for (INT I = 0; I <= datatable. columns. count-1; I ++) %> <br/> <% {%> <br/> private <% = datatable. columns [I]. systemtype %> m <% = datatable. columns [I]. name % >;< br/><%}%> </P> <p> <% for (INT I = 0; I <= datatable. columns. count-1; I ++) %> <br/> <% {%> <br/> Public <% = datatable. columns [I]. systemtype %> <% = datatable. columns [I]. name %> <br/> {<br/> Get <br/> {<br/> return m <% = dat Atable. columns [I]. name % >;< br/>}< br/> set <br/>{< br/> m <% = datatable. columns [I]. name %> = value; <br/>}< br/> <% }%> <br/> # endregion <br/>}</P> <p> /// <summary> <br/> // The data object of <% = This. datatable. name %> <br/> /// </Summary> <br/> Public partial class <% = getclassname (1) %>: database <br/> {<br/> private string strerr = string. empty; </P> <p> # region field attribute <br/> private <% = GETC Lassname (0) %> DATA = new <% = getclassname (0) %> (); <br/> <% for (INT I = 0; I <= datatable. columns. count-1; I ++) %> <br/> <% {%> <br/> Public <% = datatable. columns [I]. systemtype %> <% = datatable. columns [I]. name %> <br/> {<br/> Get <br/> {<br/> return data. <% = datatable. columns [I]. name % >;< br/>}< br/> set <br/>{< br/> data. <% = datatable. columns [I]. name %> = value; <br/>}< br/> <% }%> <br/> # endregion </P> <p> pub LIC <% = getclassname (1) %> () <br/>{< br/>}</P> <p> // <summary> <br/> // delete current record <br/> /// </Summary> <br/> // <returns> </returns> <br/> Public Boolean Delete (out string strerror) <br/>{< br/> strerror = string. empty; <br/> string strsql = "<% = getdeletesql (datatable) %> "; <br/> try <br/>{< br/> <% IF (datatable. hasprimarykey) %> <br/> <% {%> <br/> oracleparameter [] objparameter = new oraclepara Meter [<% = datatable. primarykey. membercolumns. count %>]; <br/> <% for (INT I = 0; I <= datatable. primarykey. membercolumns. count-1; I ++) %> <br/> <% {%> <br/> objparameter [<% = I %>] = new oracleparameter ("<% = datatable. primarykey. membercolumns [I]. name %> ", oracletype. <% = getsqltypeformdbtype (datatable. primarykey. membercolumns [I]. datatype) %>); <br/> objparameter [<% = I %>]. value = This. <% = datatable. primarykey. me Mbercolumns [I]. name % >;< br/><%}%> </P> <p> If (! Execcmdbysql (strsql, objparameter, out strerr) <br/> throw new exception (strerr); <br/> clearvalue (); <br/>}< br/> catch (exception e) <br/>{< br/> strerror = E. message; <br/> return false; <br/>}</P> <p> return true; <br/>}< br/>

Execute the template and specify a table for the attribute to generate code smoothly.

But if a system has dozens or even hundreds of tables, do you need to generate them all over again? Next we will solve this problem.

Create a dashboard and enter the following code to save it as generatealltmp. CST.

<% @ Codetemplate Language = "C #" targetlanguage = "text" Description = "" %> <br/> <% @ register name = "dataobject" template = "C: /users/Wenliu/documents/codesmith/templates/oracletier/dataobjecttmp. CST "mergeproperties =" false "excludeproperties =" "%> <br/> <% @ Assembly name =" schemaexplorer "%> <br/> <% @ Assembly name =" codesmith. basetemplates "%> <br/> <% @ import namespace =" codesmith. basetemplates "%> <br/> <% @ I Mport namespace = "schemaexplorer" %> <br/> <% @ property name = "Database" type = "databaseschema" Category = "context" Optional = "true" Description = "If generate by database, please set this property "%> <br/> <MCE: script runat =" template "> <! -- <Br/> private dataobject objsubtemplate = new dataobject (); <br/> Public void outputsubtemplate () <br/>{< br/> for (INT I = 0; I <database. tables. count; I ++) <br/> generatefile (database. tables [I]); <br/>}</P> <p> Public void generatefile (tableschema table) <br/>{< br/> string strfilename = "", strcontent = "", stroldcontend = ""; <br/> objsubtemplate. setproperty ("datatable", table); <br/> strfilename = @ "D:/projects/" + table. name + ". CS "; <br/> objsubtemplate. rendertofile (strfilename, true); <br/>}< br/> // --> </MCE: SCRIPT> </P> <p> <% outputsubtemplate (); %>

In this template, the sub-template is registered first, and then the sub-template is called cyclically based on the database specified by the user, and the results of each call are written into the user-specified folder.

 

2. the batch generation problem is solved, but in practice our database is often adjusted. After each adjustment, we need to re-generate the data layer. However, at this time, because the pre-generated data layer method is not enough, we have already added some methods to the data layer. At this time, how can we keep the code added by the user to cover only the part generated by Smith? Next we will solve this problem.

Modify the sub-template as follows:

............................. <Br/> the omitted content is the sub-template content described in (1) <br/> the following content is newly added </P> <p> // flag: auto generated over this behavior codesmith Code Generation ID line <br/> // user add code area <br/> namespace dataaccess <br/>{< br/> Public partial class <% = getclassname (1) %>: database <br/>{</P> <p >}< br/>

Then, modify the motherboard as follows:

<% @ Codetemplate Language = "C #" targetlanguage = "text" Description = "" %> <br/> <% @ register name = "dataobject" template = "C: /users/Wenliu/documents/codesmith/templates/oracletier/dataobject. CST "mergeproperties =" false "excludeproperties =" "%> <br/> <% @ Assembly name =" schemaexplorer "%> <br/> <% @ Assembly name =" codesmith. basetemplates "%> <br/> <% @ import namespace =" codesmith. basetemplates "%> <br/> <% @ impo RT namespace = "schemaexplorer" %> <br/> <% @ property name = "Database" type = "databaseschema" Category = "context" Optional = "true" Description = "If generate by database, please set this property "%> <br/> <MCE: script runat =" template "> <! -- <Br/> private dataobject objsubtemplate = new dataobject (); <br/> Public void outputsubtemplate () <br/>{< br/> for (INT I = 0; I <database. tables. count; I ++) <br/> generatefile (database. tables [I]); <br/>}</P> <p> Public void generatefile (tableschema table) <br/>{< br/> string strfilename = "", strcontent = "", stroldcontend = ""; <br/> objsubtemplate. setproperty ("datatable", table); <br/> strfilename = @ "D:/projects/" + table. name + ". CS "; <br/> If (system. io. file. exists (strfilename) <br/>{< br/> strcontent = objsubtemplate. rendertostring (); <br/> system. io. streamreader sr = new system. io. streamreader (strfilename); <br/> stroldcontend = sr. readtoend (); <br/> Sr. close (); <br/> strcontent = strcontent. substring (0, strcontent. indexof ("// flag:") + stroldcontend. substring (stroldcontend. indexof ("// flag:"); <br/> system. io. filestream FS = new system. io. filestream (strfilename, system. io. filemode. truncate); <br/> system. io. streamwriter Sw = new system. io. streamwriter (FS); <br/> SW. write (strcontent); <br/> FS. flush (); <br/> SW. close (); <br/> FS. close (); <br/>}< br/> else <br/> objsubtemplate. rendertofile (strfilename, true); <br/>}< br/> // --> </MCE: SCRIPT> </P> <p> <% outputsubtemplate (); %>

In the master, files are directly generated for newly added tables. For existing data-layer code files, the code is replaced based on the "flag" in the file and the user is retained to add code.

 

3. Another problem is that if you only want to generate the data layer of a single table, what should we do? There is no need to re-traverse and generate the entire data? Next we will solve this problem.

Modify the master and add a able attribute to the master board as follows:

<% @ Codetemplate Language = "C #" targetlanguage = "text" Description = "" %> <br/> <% @ register name = "dataobject" template = "C: /users/Wenliu/documents/codesmith/templates/oracletier/dataobject. CST "mergeproperties =" false "excludeproperties =" "%> <br/> <% @ Assembly name =" schemaexplorer "%> <br/> <% @ Assembly name =" codesmith. basetemplates "%> <br/> <% @ import namespace =" codesmith. basetemplates "%> <br/> <% @ impo RT namespace = "schemaexplorer" %> <br/> <% @ property name = "Database" type = "databaseschema" Category = "context" Optional = "true" Description = "If generate by database, please set this property "%> <br/> <% @ property name =" datatable "type =" tableschema "Category =" context "Optional =" true "Description =" If generate by table, please set this property "%> <br/> <MCE: script runat =" template "> <! -- <Br/> private dataobject objsubtemplate = new dataobject (); <br/> Public void outputsubtemplate () <br/>{< br/> If (datatable! = NULL) <br/> generatefile (datatable); <br/> else <br/> {<br/> for (INT I = 0; I <database. tables. count; I ++) <br/> generatefile (database. tables [I]); <br/>}</P> <p> Public void generatefile (tableschema table) <br/>{ <br/> string strfilename = "", strcontent = "", stroldcontend = ""; <br/> objsubtemplate. setproperty ("datatable", table); <br/> strfilename = @ "D:/projects/" + table. name + ". CS "; <br/> If (system. io. file. exists (strfilename) <br/>{< br/> strcontent = objsubtemplate. rendertostring (); <br/> system. io. streamreader sr = new system. io. streamreader (strfilename); <br/> stroldcontend = sr. readtoend (); <br/> Sr. close (); <br/> strcontent = strcontent. substring (0, strcontent. indexof ("// flag:") + stroldcontend. substring (stroldcontend. indexof ("// flag:"); <br/> system. io. filestream FS = new system. io. filestream (strfilename, system. io. filemode. truncate); <br/> system. io. streamwriter Sw = new system. io. streamwriter (FS); <br/> SW. write (strcontent); <br/> FS. flush (); <br/> SW. close (); <br/> FS. close (); <br/>}< br/> else <br/> objsubtemplate. rendertofile (strfilename, true); <br/>}< br/> // --> </MCE: SCRIPT> </P> <p> <% outputsubtemplate (); %>

At this time, if you specify a single table, it will be generated according to the specified table. If you specify a database, it will traverse the data layer code that generates all the tables of the entire database.

 

Conclusion: In fact, codesmith almost supports all the common functions under. net. The above is just a small test, which can be generated and replaced as needed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.