今天,从别的电脑上拷贝了CodeSmith的模板到手提电脑上,执行时报出了“调用的目标发生了异常”,由于在拷贝的电脑上执行是完全没问题的,开始以为是安装了的CodeSmith有问题,重装后,还是同样出現该问题,在开始执行的第一步,输入Response.WriteLine("aaa");再次执行,也报出这个错误,并且输出里面根本就没有打印出"aaa"这个字符串。对于该情况,真的是一头雾水,怀疑是不是模板有什么问题,于是,执行别的有批量文件输出的模板执行一下,竟然能成功,于是,排除掉了CodeSmith的问题。最后,尝试代码注释法,看看会不会有效,把Response.WriteLine("aaa");后面的所有代码都注释掉。竟然能在输出的位置看到了"aaa"这字符串输出。于是,逐步取消后面注释掉的代码,在紧跟着执行到:
compiler.Compile();
if (compiler.Errors.Count == 0 )
{
return compiler.CreateInstance();
}
在替换掉templateName时,替换成其中一个模板,“D:\\My Documents\\CodeSmith\\Samples\\v5.2\\Templates\\zhaogw\\piggy\\piggy_BLL.cst”,然后执行,竟然成功了,但把这个取消,执行一下,还是报这个错,最后,把执行的模板名称输出到控制台,于是,把templateName替换成,“D:\\My Documents\\CodeSmith\\Samples\\v5.2\\Templates\\zhaogw\\piggy\\piggy_projectFileInclue.cst”时,竟然会报错,于是,确定了是piggy_projectFileInclue.cst出了问题,双击该模板,提示有错误,经检查,出错的位置是
这才想起,我本地数据库中根本就没有了ggjj这个库,于是,把默认值都去掉了,再检查其它模板,把同样的情况都去掉后,再次执行,错误消失了,成功输出了所有文件。
总结经验教训:CodeSmith中的模板,在设置默认值的时候,不能依赖与本身的环境,就像这次的,这里的默认值设置了别的电脑上不一定存在的数据库而报错的,因此,最好这些有依赖性的设置,都设置成空的默认值。还有一个情况,就是输出页根本就不会输出信息的问题,在没有注释后面代码时,编译又能通过的情况下,已经执行过的代码,输出页面也没有任何信息输出,但却报出错误,这种情况比较特殊,一般情况下的错误,只要执行了Response.WriteLine("aaa");基本上都会在输出页面输出aaa字符串的,这里在执行到return compiler.CreateInstance();报错,竟然会导致输出页面没有输出aaa字符串,这个问题也值得关注。否则,错误跟踪的方法就要适当的改变一下。
下面,贡献下本人的批量模板的批量表输出的脚本,仅供参考:
<%-- Context --%>
<%-- Object --%>
<% @ Property Name = " NameSpace " Type = " System.String " Default = " NameSpace " Category = " Object " Description = " 项目的命名空间 " %>
<% @ Property Name = " Assembly " Type = " System.String " Default = " Assembly " Category = " Object " Description = " 项目的程序集 " %>
<% @ Property Name = " TableDivideMark " Type = " System.String " Default = " _ " Category = " Object " Description = " 表名分隔符 " %>
<% @ Property Name = " TablePrefix " Type = " System.Boolean " Default = " true " Category = " Object " Description = " 是否有表前缀,如果存在表前缀的,会自动把第一个表名分隔符前的表前缀删除掉。 " %>
<% @ Property Name = " TablePrefixLength " Type = " System.Int32 " Default = " 4 " Category = " Object " Description = " 表前缀长度,如果表前缀大于这个值,则认为没有表前缀 " %>
<% @ Property Name = " ColumnDivideMark " Type = " System.String " Default = " _ " Category = " Object " Description = " 字段名分隔符 " %>
<% @ Property Name = " ColumnPrefix " Type = " System.Boolean " Default = " false " Category = " Object " Description = " 是否有字段前缀,如果存在字段前缀的,会自动把第一个字段名分隔符前的字段前缀删除掉。 " %>
<% @ Property Name = " ColumnPrefixLength " Type = " System.Int32 " Default = " 0 " Category = " Object " Description = " 字段前缀长度,如果字段前缀大于这个值,则认为没有字段前缀 " %>
<% @ Property Name = " ForceId " Type = " System.Boolean " Default = " true " Category = " Object " Description = " 强制性自增量标识主键 " %>
<% @ Property Name = " ForceIdProperty " Type = " System.String " Default = " ID " Category = " Object " Description = " 强制性自增量标识主键的属性名称 " %>
<% @ Property Name = " SourceTableNames " Type = " System.String " Default = "" Category = " Object " Description = " 当指定表名时,只执行字符串中表名列表中的表 " %>
<%-- Context --%>
<% @ Assembly Name = " System.Design " %>
<% @ Assembly Name = " SchemaExplorer " %>
<% @ Import Namespace = " SchemaExplorer " %>
<% @ Import Namespace = " System.IO " %>
<% @ Import Namespace = " System.Xml " %>
<% @ Import Namespace = " System.Text " %>
<% @ Import Namespace = " System.Windows.Forms.Design " %>
<% @ Import Namespace = " System.Text.RegularExpressions " %>
<% @ Import Namespace = " System.Collections.Specialized " %>
< script runat = " template " >
private DatabaseSchema _sourceDatabase;
private string _outputDirectory;
private bool _implementNotification = true ;
// 模板对象列表(根据模板名称产生出来的模板对象)
public CodeTemplate[] CurrentTemplates;
// 模板名称数组
public string [] TemplateNames = { " piggy_projectFileInclue.cst " , " piggy_SqlMap.config.cst " , " piggy_dao.config.cst " , " piggy_service.config.cst " , " piggy_Model_Auto.cst " , " iBatis_sqlmap_Auto.cst " , " piggy_Service.cst " , " piggy_Model.cst " , " piggy_DAL.cst " , " piggy_BLL.cst " , " iBatis_sqlmap.cst " };
// 模板输出格式数组
public string [] strFormats = { " projectFileInclue.txt " , " sqlmap.config " , " Dao_Auto.config " , " Service_Auto.config " , " {0}_Auto.cs " , " {0}_Auto.xml " , " I{0}BLL.cs " , " {0}.cs " , " {0}DAO.cs " , " {0}BLL.cs " , " {0}.xml " };
// 模板输出路径
public string [] OutputPaths = { "" , " \\Data " , " \\Data\\config " , " \\Data\\config " , " \\Data_Auto\\Model " , " \\Data_Auto\\Map " , " \\Data\\service " , " \\Data\\Model " , " \\Data\\DAL " , " \\Data\\BLL " , " \\Data\\Map " };
[Category( " Database " )]
[Description( " Database that the mapping file should be based on. " )]
public DatabaseSchema SourceDatabase {
get { return _sourceDatabase; }
set { _sourceDatabase = value; }
}
[Editor( typeof (System.Windows.Forms.Design.FolderNameEditor), typeof (System.Drawing.Design.UITypeEditor))]
[Category( " Class " )]
[Description( " The folder to save the generated class files. " )]
public string OutputDirectory
{
get { return _outputDirectory;}
set {_outputDirectory = value;}
}
// 根据模板名称产生出来的模板对象列表
public void CreateTemplate()
{
if (CurrentTemplates == null )
{
CurrentTemplates = new CodeTemplate[TemplateNames.Length];
for ( int i = 0 ; i < TemplateNames.Length; i ++ )
{
CurrentTemplates[i] = CompileTemplate(CodeTemplateInfo.DirectoryName + TemplateNames[i]);
}
}
}
// 单独生成一个模板对象
public CodeTemplate CompileTemplate( string templateName)
{
CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateName);
compiler.Compile();
if (compiler.Errors.Count == 0 )
{
return compiler.CreateInstance();
}
else
{
for ( int i = 0 ; i < compiler.Errors.Count; i ++ )
{
Response.WriteLine(compiler.Errors[i].ToString());
}
return null ;
}
}
// 执行输出脚本
public void Generate()
{
if (CurrentTemplates == null )
CreateTemplate();
StringCollection ExcludedTables = new StringCollection();
if (SourceTableNames.Length > 0 )
{
int mIndex =- 1 ;
mIndex = SourceTableNames.IndexOf( ' , ' );
while (mIndex > 0 ) {
ExcludedTables.Add(SourceTableNames.Substring( 0 ,mIndex));
SourceTableNames = SourceTableNames.Remove( 0 ,mIndex + 1 );
mIndex = SourceTableNames.IndexOf( ' , ' );
}
ExcludedTables.Add(SourceTableNames);
}
foreach (TableSchema SourceTable in SourceDatabase.Tables)
{
if (SourceTableNames.Length > 0 )
{
if ( ! ExcludedTables.Contains(SourceTable.Name))
continue ;
}
Response.Write( string .Format( " Processing Table {0} ... " , SourceTable.Name));
Response.WriteLine();
try
{
string className = ClearDivideMarkAndPrefix(SourceTable.Name,TableDivideMark,TablePrefix,TablePrefixLength);
for ( int i = 0 ; i < TemplateNames.Length; i ++ )
{
string FileName;
if (i <= 3 )
{
CurrentTemplates[i].SetProperty( " SourceDatabase " , SourceDatabase);
FileName = strFormats[i];
}
else {
CurrentTemplates[i].SetProperty( " SourceTable " , SourceTable);
FileName = string .Format(strFormats[i],className);
}
FileName = Path.Combine(OutputDirectory + OutputPaths[i], FileName);
// 统一属性赋值
CurrentTemplates[i].SetProperty( " NameSpace " ,NameSpace);
CurrentTemplates[i].SetProperty( " Assembly " ,Assembly);
CurrentTemplates[i].SetProperty( " TableDivideMark " ,TableDivideMark);
CurrentTemplates[i].SetProperty( " TablePrefix " ,TablePrefix);
CurrentTemplates[i].SetProperty( " TablePrefixLength " ,TablePrefixLength);
CurrentTemplates[i].SetProperty( " ColumnDivideMark " ,ColumnDivideMark);
CurrentTemplates[i].SetProperty( " ColumnPrefix " ,ColumnPrefix);
CurrentTemplates[i].SetProperty( " ColumnPrefixLength " ,ColumnPrefixLength);
CurrentTemplates[i].SetProperty( " ForceId " ,ForceId);
CurrentTemplates[i].SetProperty( " ForceIdProperty " ,ForceIdProperty);
Response.WriteLine( string .Format( " {0} In {1} " , TemplateNames[i],FileName));
CurrentTemplates[i].RenderToFile(FileName, true );
}
}
catch (Exception ex)
{
Response.WriteLine( " Error: " + ex);
}
}
}
</ script >
<% this .Generate(); %>
<!-- #include file = " Function.inc " -->
如果编译出错时,应该是ClearDivideMarkAndPrefix函数没有定义,这里,这个函数不重要了,各位可以根据自己需要来修改罗。
原创作品出自努力偷懒,转载请说明文章出处:http://www.cnblogs.com/kfarvid/