今天又根据CodeSmith的几个基本组件写出了基于表生成删除功能的存储过程代码生成模板。
昨天觉得添加的存储过程模板写的比较简单,今天准备详细介绍一下这个删除的模板。
首先介绍我们使用到的一个教本函数GetSqlParameterStatement(ColumnSchema column),其函数代码如下:
1
public
string
GetSqlParameterStatement(ColumnSchema column)
2
{
3 string param = "@" + column.Name + " " + column.NativeType;
4 switch (column.DataType)
5 {
6 case DbType.Decimal:
7 {
8 param += "(" + column.Precision + ", " + column.Scale + ")";
9 break;
10 }
11 default:
12 {
13 if (column.Size > 0)
14 {
15 param += "(" + column.Size + ")";
16 }
17 break;
18 }
19 }
20 return param;
21}
大家可以看到,这个函数需要传入一个ColumnSchema类型的参数,它代表一个数据表中的列,并且是一个列,然后根据ColumnSchema这个类具有的属性,对传入的列进行一些操作然后返回我们生成存储过程时需要的代码。
首先介绍一下ColumnSchema的一些常用属性,如下表:
属性Property |
描述Description |
AllowDBNull |
是否允许空值NULL |
Database |
通过DatabaseSchema对象得到当前列所属的数据库 |
DataType |
此数据对象的数据类型 |
Description |
当前对象的描述 |
ExtendedProperties |
用来存储SchemaObject的其他附加信息 |
IsForeignKeyMember |
当前列是否为外键 |
IsPrimaryKeyMember |
当前列是否为主键 |
IsUnique |
当前列是否唯一 |
Name |
列的名称 |
NativeType |
列定义的数据类型 |
Precision |
数据对象的精度 |
Scale |
数据对象的范围(个人理解为需要保留小数的范围) |
Size |
数据对象的大小(例如:字符串长度为10) |
SystemType |
数据对象的系统类型 |
Table |
当前列所属的数据表 |
下面为我们首先要生成存储过程,要自动生成的代码分成了红、绿、蓝三部分。
CREATE PROCEDURE dbo.Customer
sD
elete
/*
==================================================
Author:Bear-Study-Hard
CreatedTime:
2005-12-28
Description:Delete a record from table Customers
==================================================
*/
@CustomerID nchar(5) --客户ID
AS
Delete From [Customers]
Where
[CustomerID] = @CustomerID
我们的这个脚本函数就是要实现拼出红色的部分,GetSqlParameterStatement函数接收到ColumnSchema类型的参数后,从其Name属性和NativeType属性拼出@CustomerID nchar部分,然后由于不同的数据类型尤其是数值类型和字符串类型的区别,会导致数据类型的大小会有所不同,这里仅对Decimal的数据类型进行了判断(Numeric和float等均需要这种处理),然后根据Precision属性得到精度并通过Scale属性得到了需要保留小数的范围。如果传出的为非Decimal类型字段则直接通过Size属性取出其大小即可。得到了(5)部分。最后的注释是为了生成的存储过程解读性好加上的,使用的是Description属性。
剩下的绿色部分和蓝色部分生成时比较简单,请各位自行学习。模板代码为:
1
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="T-SQL"
Description
="Create a procedure which have delete function base on a table.Must use PrimaryKey to delete a record."
%
>
2
<
%@ Assembly
Name
="SchemaExplorer"
%
>
3
<
%@ Import
Namespace
="SchemaExplorer"
%
>
4
<
%@ Property
Name
="SourceTable"
Type
="SchemaExplorer.TableSchema"
Category
="DataTable"
Description
="Table that the stored procedures should be based on."
%
>
5
<
%@ Property
Name
="Author"
Type
="String"
Category
="Context"
Description
="The author for this procedure."
Optional
="true"
%
>
6
<
%@ Property
Name
="Description"
Type
="String"
Category
="Context"
Description
="The description for this procedure."
Optional
="true"
%
>
7
<
script
runat
="template"
>
8
public string GetSqlParameterStatement(ColumnSchema column)
9
{
10
string param = "@" + column.Name + " " + column.NativeType;
11
switch (column.DataType)
12
{
13
case DbType.Decimal:
14
{
15
param += "(" + column.Precision + ", " + column.Scale + ")";
16
break;
17
}
18
default:
19
{
20
if (column.Size > 0)
21
{
22
param += "(" + column.Size + ")";
23
}
24
break;
25
}
26
}
27
return param;
28
}
29
</
script
>
30
CREATE PROCEDURE dbo.
<
%=SourceTable
.Name %
>
Delete
31
/*
32
==================================================
33
Author:
<
%= Author
%
>
34
CreatedTime:
<
%= System
.DateTime.Now.ToShortDateString() %
>
35
Description:
<
%= Description
%
>
36
==================================================
37
*/
38
<
% for
(int i
= 0;
i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %
>
39
<
%= GetSqlParameterStatement
(SourceTable.PrimaryKey.MemberColumns[i]) %
><
% if
(i < SourceTable.PrimaryKey.MemberColumns.Count - 1) { %
>
,
<
% } %
>
<
% if
(SourceTable.Columns[i].Description !
= ""
) { %
>
--
<
%= SourceTable
.Columns[i].Description %
><
% } %
>
40
<
% } %
>
41
AS
42
Delete From [
<
%= SourceTable
.Name %
>
]
43
Where
44
<
% for
(int i
= 0;
i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %
>
45
<
% if
(i
>
0) { %>AND
<
% } %
>
[
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
] = @
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
46
<
% } %
>
posted @
2006-04-13 17:06 jirong 阅读(362) |
评论 (0) |
编辑
今天又根据CodeSmith的几个基本组件写出了基于表生成删除功能的存储过程代码生成模板。
昨天觉得添加的存储过程模板写的比较简单,今天准备详细介绍一下这个删除的模板。
首先介绍我们使用到的一个教本函数GetSqlParameterStatement(ColumnSchema column),其函数代码如下:
1
public
string
GetSqlParameterStatement(ColumnSchema column)
2
{
3 string param = "@" + column.Name + " " + column.NativeType;
4 switch (column.DataType)
5 {
6 case DbType.Decimal:
7 {
8 param += "(" + column.Precision + ", " + column.Scale + ")";
9 break;
10 }
11 default:
12 {
13 if (column.Size > 0)
14 {
15 param += "(" + column.Size + ")";
16 }
17 break;
18 }
19 }
20 return param;
21}
大家可以看到,这个函数需要传入一个ColumnSchema类型的参数,它代表一个数据表中的列,并且是一个列,然后根据ColumnSchema这个类具有的属性,对传入的列进行一些操作然后返回我们生成存储过程时需要的代码。
首先介绍一下ColumnSchema的一些常用属性,如下表:
属性Property |
描述Description |
AllowDBNull |
是否允许空值NULL |
Database |
通过DatabaseSchema对象得到当前列所属的数据库 |
DataType |
此数据对象的数据类型 |
Description |
当前对象的描述 |
ExtendedProperties |
用来存储SchemaObject的其他附加信息 |
IsForeignKeyMember |
当前列是否为外键 |
IsPrimaryKeyMember |
当前列是否为主键 |
IsUnique |
当前列是否唯一 |
Name |
列的名称 |
NativeType |
列定义的数据类型 |
Precision |
数据对象的精度 |
Scale |
数据对象的范围(个人理解为需要保留小数的范围) |
Size |
数据对象的大小(例如:字符串长度为10) |
SystemType |
数据对象的系统类型 |
Table |
当前列所属的数据表 |
下面为我们首先要生成存储过程,要自动生成的代码分成了红、绿、蓝三部分。
CREATE PROCEDURE dbo.Customer
sD
elete
/*
==================================================
Author:Bear-Study-Hard
CreatedTime:
2005-12-28
Description:Delete a record from table Customers
==================================================
*/
@CustomerID nchar(5) --客户ID
AS
Delete From [Customers]
Where
[CustomerID] = @CustomerID
我们的这个脚本函数就是要实现拼出红色的部分,GetSqlParameterStatement函数接收到ColumnSchema类型的参数后,从其Name属性和NativeType属性拼出@CustomerID nchar部分,然后由于不同的数据类型尤其是数值类型和字符串类型的区别,会导致数据类型的大小会有所不同,这里仅对Decimal的数据类型进行了判断(Numeric和float等均需要这种处理),然后根据Precision属性得到精度并通过Scale属性得到了需要保留小数的范围。如果传出的为非Decimal类型字段则直接通过Size属性取出其大小即可。得到了(5)部分。最后的注释是为了生成的存储过程解读性好加上的,使用的是Description属性。
剩下的绿色部分和蓝色部分生成时比较简单,请各位自行学习。模板代码为:
1
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="T-SQL"
Description
="Create a procedure which have delete function base on a table.Must use PrimaryKey to delete a record."
%
>
2
<
%@ Assembly
Name
="SchemaExplorer"
%
>
3
<
%@ Import
Namespace
="SchemaExplorer"
%
>
4
<
%@ Property
Name
="SourceTable"
Type
="SchemaExplorer.TableSchema"
Category
="DataTable"
Description
="Table that the stored procedures should be based on."
%
>
5
<
%@ Property
Name
="Author"
Type
="String"
Category
="Context"
Description
="The author for this procedure."
Optional
="true"
%
>
6
<
%@ Property
Name
="Description"
Type
="String"
Category
="Context"
Description
="The description for this procedure."
Optional
="true"
%
>
7
<
script
runat
="template"
>
8
public string GetSqlParameterStatement(ColumnSchema column)
9
{
10
string param = "@" + column.Name + " " + column.NativeType;
11
switch (column.DataType)
12
{
13
case DbType.Decimal:
14
{
15
param += "(" + column.Precision + ", " + column.Scale + ")";
16
break;
17
}
18
default:
19
{
20
if (column.Size > 0)
21
{
22
param += "(" + column.Size + ")";
23
}
24
break;
25
}
26
}
27
return param;
28
}
29
</
script
>
30
CREATE PROCEDURE dbo.
<
%=SourceTable
.Name %
>
Delete
31
/*
32
==================================================
33
Author:
<
%= Author
%
>
34
CreatedTime:
<
%= System
.DateTime.Now.ToShortDateString() %
>
35
Description:
<
%= Description
%
>
36
==================================================
37
*/
38
<
% for
(int i
= 0;
i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %
>
39
<
%= GetSqlParameterStatement
(SourceTable.PrimaryKey.MemberColumns[i]) %
><
% if
(i < SourceTable.PrimaryKey.MemberColumns.Count - 1) { %
>
,
<
% } %
>
<
% if
(SourceTable.Columns[i].Description !
= ""
) { %
>
--
<
%= SourceTable
.Columns[i].Description %
><
% } %
>
40
<
% } %
>
41
AS
42
Delete From [
<
%= SourceTable
.Name %
>
]
43
Where
44
<
% for
(int i
= 0;
i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %
>
45
<
% if
(i
>
0) { %>AND
<
% } %
>
[
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
] = @
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
46
<
% } %
>
posted @
2006-04-13 17:05 jirong 阅读(173) |
评论 (0) |
编辑
这个例子仅是一个简单的应用,在我翻译并学习完CodeSmith的英文帮助文档后,对CodeSmith有了一定的了解,开始着手编写一些CodeSmith应用模板,今天按照最早提到的例子自行编写了一个基于表的添加存储过程的生成模板。具体语法前面基础中已做过详细解释这里仅是一个小综合应用的例子,望对大家学习CodeSmith有很好的帮助。我的同事也写了几个CodeSmith的技巧的文章
http://terrylee.cnblogs.com/
大家有空去看看,写的很不错哦,都是针对于CodeSmith自定义属性编写的东东:)
1
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="T-SQL"
Description
="Create a procedure which have insert function base on a table."
%
>
2
<
%@ Assembly
Name
="SchemaExplorer"
%
>
3
<
%@ Import
Namespace
="SchemaExplorer"
%
>
4
<
%@ Property
Name
="SourceTable"
Type
="SchemaExplorer.TableSchema"
Category
="DataTable"
Description
="Table that the stored procedures should be based on."
%
>
5
<
%@ Property
Name
="Author"
Type
="String"
Category
="Context"
Description
="The author for this procedure."
%
>
6
<
%@ Property
Name
="Description"
Type
="String"
Category
="Context"
Description
="The description for this procedure."
%
>
7
<
script
runat
="template"
>
8
public string GetSqlParameterStatement(ColumnSchema column)
9
{
10
string param = "@" + column.Name + " " + column.NativeType;
11
switch (column.DataType)
12
{
13
case DbType.Decimal:
14
{
15
param += "(" + column.Precision + ", " + column.Scale + ")";
16
break;
17
}
18
default:
19
{
20
if (column.Size > 0)
21
{
22
param += "(" + column.Size + ")";
23
}
24
break;
25
}
26
}
27
return param;
28
}
29
</
script
>
30
CREATE PROCEDURE dbo.
<
%=SourceTable
.Name %
>
Insert
31
/*
32
==================================================
33
Author:
<
%= Author
%
>
34
CreatedTime:
<
%= System
.DateTime.Now.ToShortDateString() %
>
35
Description:
<
%= Description
%
>
36
==================================================
37
*/
38
<
% for
(int i
= 0;
i < SourceTable.Columns.Count; i++) { %
>
39
<
%= GetSqlParameterStatement
(SourceTable.Columns[i]) %
><
% if
(i < SourceTable.Columns.Count - 1) { %
>
,
<
% } %
>
<
% if
(SourceTable.Columns[i].Description !
= ""
) { %
>
--
<
%= SourceTable
.Columns[i].Description %
><
% } %
>
40
<
% } %
>
41
AS
42
Insert Into [
<
%= SourceTable
.Name %
>
]
43
(
44
<
% for
(int i
= 0;
i < SourceTable.Columns.Count; i++) { %
>
45
[
<
%= SourceTable
.Columns[i].Name %
>
]
<
% if
(i < SourceTable.Columns.Count - 1) { %
>
,
<
% } %
>
<
% if
(SourceTable.Columns[i].Description !
= ""
) { %
>
--
<
%= SourceTable
.Columns[i].Description %
><
% } %
>
46
<
% } %
>
47
)
48
Values
49
(
50
<
% for
(int i
= 0;
i < SourceTable.Columns.Count; i++) { %
>
51
@
<
%= SourceTable
.Columns[i].Name %
><
% if
(i < SourceTable.Columns.Count - 1) { %
>
,
<
% } %
>
52
<
% } %
>
53
)
posted @
2006-04-13 17:02 jirong 阅读(336) |
评论 (0) |
编辑
摘要: 编写CodeSmith自定义属性的编辑器(Writing Custom Property Editors) 当你开始编写自定义的CodeSmith模板时,很可能对于使用它的strings或integers属性很满意,但有时你会发现需要创建一个不同类型的属性,可能是一个自定义的类型或者是.NET framework中但是在属性面板中没有提供的类型。在模板中去作这些很简单,但是怎样指定一个类型在运行模...
阅读全文
posted @
2006-04-13 17:00 jirong 阅读(205) |
评论 (0) |
编辑
本文翻译的内容为CodeSmith控制台指南。
很多人仅仅知道CodeSmith像一个图形应用程序,或者可能是一个Visual Studio的附件,但是通过CodeSmith的控制台应用程序还有好多其他的使用方法。控制台应用程序是很有价值的,因为可以通过它去生成脚本,或者其他一些自动工具。这篇文档的目的就是要告诉你怎样使用它的控制台应用程序并且如何去定义变量和参数。
Basic Usage
大多数情况下是用控制台应用程序来创建一个模板,一个属性文件,然后保存输出的文件。这有一个很好的例子介绍将合并模版的处理过程放到一个过程中,就像使用NAnt工具。
首先我们要确定完成一个什么样的模版,为这个模板创建一个什么样的XML属性文件。XML属性文件提供在执行模版是需要的各个属性。生成一个属性文件最简单的方法是在CodeSmith Explorer中打开一个模版,填写属性,点击生成按钮generate,然后再点击Save Property Set XML按钮。这个按钮会在点击完生成按钮后找到,在Save Output和Copy Output按钮旁边。然后系统提示输入保存XML属性文件的文件名,下面看一个ArrayList.cst模版创建的XML属性文件。
1
<?
xml version="1.0" encoding="us-ascii"
?>
2
<
codeSmith
>
3
<
propertySet
>
4
<
property
name
="Accessibility"
>
Public
</
property
>
5
<
property
name
="ClassName"
>
PersonArray
</
property
>
6
<
property
name
="ItemType"
>
Person
</
property
>
7
<
property
name
="ItemValueType"
>
False
</
property
>
8
<
property
name
="ItemCustomSearch"
>
False
</
property
>
9
<
property
name
="KeyName"
>
PersonID
</
property
>
10
<
property
name
="KeyType"
>
int
</
property
>
11
<
property
name
="IncludeInterfaces"
>
True
</
property
>
12
<
property
name
="IncludeNamespaces"
>
False
</
property
>
13
</
propertySet
>
14
</
codeSmith
>
就像看到的一样,也可以手动创建这个文件,但是使用CodeSmith Explorer会更简便。
现在我们有了这个XML文件,我们继续看一下如何去执行这个模版并是用控制台工具保存结果。首先我们需要是用/template参数去声明我们要是用的模版,像这样:
C:\Program Files\CodeSmith\v3.0>cs /template:Samples\Collections\ArrayList.cst
在这个例子中我们使用了ArrayList.cst模版,它存储在本地的Samples\Collections文件夹下。下一步我们要去声明我们在最后一步需要创建的XML文件,我们是用/propertyset参数去实现。
C:\Program Files\CodeSmith\v3.0>cs /template:Samples\Collections\ArrayList.cst /propertyset:PersonArray.xml
这个/property参数用来指定我们的XML属性文件。最后一个我们需要用的参数是/output参数,用来指定输出怎样被保存。
C:\Program Files\CodeSmith\v3.0>cs /template:Samples\Collections\ArrayList.cst /propertyset:PersonArray.xml /out:test.cs
使用/out参数指定将结果输出到一个叫test.cs文件中保存。执行这个命令后,模板将开始运行,使用属性文件将结果输出到test.cs文件保存。
这是大多数情况下有效使用控制台。
Merging Output
在各种代码生成中最大的挑战就是将生成的代码和开发人员编写或修改的代码区分开。控制台对这个问题提供了一个有效的独特的解决方案,使用一个指定的参数在当前已存在的代码文件中需要将模板生成的代码添加的地方指定一块区域。
下面是一个简单的代码文件,包含了我们要添加生成代码的区域。
1
using
System;
2
3
namespace
Entities
4
{
5 GeneratedOrderEntity#region GeneratedOrderEntity
6
7
8 #endregion
9}
我们的目标是将DatabaseSchema\BusinessObject.cst模版生成的代码添加到类文件的GeneratedOrderEntity区域中。和上一个例子一样,使用CodeSmith console控制台应用程序执行这个模版,但是这次要使用另一个参数merge。
C:\Program Files\CodeSmith\v3.0>cs /template:Samples\DatabaseSchema\BusinessObject.cst /propertyset:OrderEntity.xml /out:OrderEntity.cs /merge:InsertRegion= "RegionName=Sample Generated Region;Language=C#;"
使用merge参数我们可以指定区域的名称,在这个例子中是GeneratedOrderEntity,然后控制台应用程序将执行模版,并将结果添加到这个区域中。我们来看一下执行完这个指令后生成的代码。
1
using
System;
2
3
namespace
Infozerk.AuthServices.UnitTestSuite
4
{
5 GeneratedOrderEntity#region GeneratedOrderEntity
6
7
8 Order#region Order
9 /**//// <summary>
10 /// This object represents the properties and methods of a Order.
11 /// </summary>
12 public class Order
13 {
14 protected int _id;
15 protected string _customerID = String.Empty;
16 protected int _employeeID;
17 protected DateTime _orderDate;
18 protected DateTime _requiredDate;
19 protected DateTime _shippedDate;
20 protected int _shipVia;
21
22--为了简短省略了类的其他部分
就像看到的一样,Order类被添加到了我们指定的区域中。在代码文件中使用merge参数生成的内容在其他部分被修改或手写后很容易重新再次生成而不会产生影响。
参数介绍Parameter Reference
Specifying Output
/out:<file>
指定从模版创建的输出文件的名称。
/out:default
指定这个文件被默认保存成模版是用的名称。
/merge:<mergetype>=<init>
指定模版输出的区域。可以简写为/m
Specifying Input
/template:<file>
选择要执行的模版,简写为/t
/propertyset:<file>
生成代码时需要使用的XML属性文件。简写为/p
Compiler Options
/debug[+|-]
指定模版需要包含的调试信息。(允许在运行模版时进行调试)
/tempfiles[+|-]
指定保留临时文件。(如果在临时文件上调试也可以)
Miscellaneous
/help
显示帮助信息。
/nologo
禁止生成器版权信息。
posted @
2006-04-13 16:58 jirong 阅读(182) |
评论 (0) |
编辑
本文主要介绍CodeSmith对象。
CodeSmith Object
CodeSimth中有许多对象可以在编写模板的时候使用,这里将介绍这些对象的一些公用方法和属性以及怎么使用它们。
代码模板对象(CodeTemplate Object)
在模板中,“this”(或者“Me”在VB.NET中)在当前模板中代码代码模板对象。
代码模板的方法(CodeTemplate Methods)
1.public virtual void GetFileName()
可以重载这个方法设置模板输出到文件的名称。否则CodeSmith将基于模板名称和TargetLanguage设置它的文件名。
2.public void CopyPropertiesTo(CodeTemplate target)
这个方法可以实现从一个模板中将其所有属性的值拷贝到另一个模板所有对应属性中,并按照相应的属性值类型进行匹配。
3.public object GetProperty(string propertyName)
这个方法将返回一个给定名称的属性的值。
4.public void SetProperty(string propertyName, object value)
此方法可以根据给定名称的属性设置其值。
5.public string SavePropertiesToXml ()
这个方法将现有的属性值保存成一个XML的属性字符串。
6.public void SavePropertiesToXmlFile (string fileName)
这个方法将当前属性值保存成一个XML的属性文件。
7.public void RestorePropertiesFromXml(string propertySetXml, string baseDirectory)
从保存在XML文件中的属性字符串,将模板的属性值恢复。
8.public void RestorePropertiesFromXmlFile(string fileName)
从保存在XML文件中的属性文件,将模板的属性值恢复。
代码模板的属性(CodeTemplate Properties)
Response:此属性可以访问当前的TextWriter对象,这个对象是用来输出模板用的。
CodeTemplateInfo:这个属性用来访问当前的CodeTemplateInfo对象,这个对象包含当前模板的一些信息。
Progress:这个属性用来报告当前模板的执行过程。
Response Object
这个对象提供直接写输出模板的方法。与ASP.NET的response对象很相似。下面是一个利用Response的Write方法在模板上输出一段文字的例子。
<% Response.Write("This will appear in the template") %>
IndentLevel (Int32)
当使用Response对象时输出文本的缩进级别。
Indent() Method
将输出缩进一个级别。
Unindent() Method
将输出少缩进一个级别。
AddTextWriter(TextWriter writer) Method
为Response对象增加一个TextWriter。这样可以使在同一时间用多个TextWriter输出模板。
CodeTemplateInfo Object
此对象包含一些当前模板的信息。下面是一些CodeTemplateInfo可用的属性。
DateCreated (DateTime)
返回一个date类型值,是模板创建的时间。
DateModified (DateTime)
返回模板最后一次被修改的时间。
Description (string)
返回模板声明时对模版的描述信息。
DirectoryName (string)
返回当前模板文件所在的路径。
FileName (string)
返回当前模版文件的文件名称。
FullPath (string)
返回当前模板的完整路径,路径名+文件名。
Language (string)
返回代码模版声明时使用的语言。
TargetLanguage (string)
返回代码模版声明时生成的目标语言。
Progress Object
这个属性用来报告当前模板的执行过程。下面是一些Progress可用的成员。
MaximumValue (Int32)
模版progress允许的最大值。
MinimumValue (Int32)
模版progress允许的最小值。
Step (Int32)
模版每执行一不progress的增长值。
Value (Int32)
Progress的当前值。
PerformStep() Method
按照指定好的progress的增加值执行一步。(原文:Perform a progress step incrementing the progress value by the amount specified in the Step property.)
Increment(Int32 amount) Method
指定progress的增加值。(原文:Increment the progress value by the specified amount.)
OnProgress (ProgressEventHandler) Event
这个事件用来报告模版的执行过程。(原文:This event can be used to be notified of template execution progress.)
1
this
.Progress.OnProgress
+=
new
ProgressEventHandler(
this
.OnProgress);
2
3
public
void
OnProgress(
object
sender, ProgressEventArgs e)
4
{
5 Trace.WriteLine(e.Value);
6}
posted @
2006-04-13 16:56 jirong 阅读(160) |
评论 (0) |
编辑
本篇将介绍CodeSmith的模版中的语法。
代码标签
<% %>
标签
可以放置任意数量的代码在其中,但并不能直接输出到模版中。
<%
foreach
(ColumnSchema column
in
SourceTable.Columns) {
%>
<%=
column.Name
%>
<%
}
%>
<%= %>标签
在模版中输出一个字符串。上例中的<%=column.Name%>
脚本标签
在这个标签中可以包含一段代码,但是他不直接影响输出的模版。可以放置一些比较有帮助的方法在其中,然后在模版的各个地方可以调用它。在脚本标签中必须包含这个参数runat=”template”,否则他会被处理成普通文本。
例:
1
<
script runat
=
"
template
"
>
2
private
string
GetColumnName(ColumnSchema cs)
3
{
4
return
cs.Name;
5
}
6
</
script
>
7
8
<%
foreach
(ColumnSchema cs
in
SourceTable.Columns) {
%>
9
<%=
GetColumnName(cs)
%>
10
<%
}
%>
使用标签可以大量减少代码,并使模版更加的易读和一管理。
Include标签
和ASP.NET一样,可以在模版中包含一些文本文件,但同ASP.NET一样它也不是总能达到你的目标。
例:
<!--
#include file="myfile.inc"
-->
有时在多个模版中引用一个组件中的功能,调用其中的方法,这时我们引用组件。但有些情况下,适用Include标签可以得到更好的效果。
Comment标签
注释标签,在前边已经做过介绍。
例:
<%
--
This
is
a comment
--
%>
posted @
2006-04-13 16:53 jirong 阅读(211) |
评论 (0) |
编辑
本文是翻译的第四篇,内容为在
CodeSmith中使用的语法和标签的参考。
CodeSmith
模板语法参考
本文的目的是在编写一个
CodeSmith模板时遇到的各种类型的变量和对象提供参考。本文的目的不是要介绍
CodeSmith,如果您想快速了解
CodeSmith请查看我翻译的
CodeSmith基础(一)和
CodeSmith基础(二)。
标签
标签一般出现在模板的头部,被用做设置许多不同的属性。
代码模板的声明(CodeTemplate Directive)
这个是模板中唯一必须的声明,包含一些模板特殊的属性,包含模板使用的语言、生成的语言和一些对于模板的描述。
例:
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="C#"
Description
="Generates a class."
%
>
参数的介绍:
Language:在开发编写模板时使用的语言,例如C#,VB.NET,Jscript等。
TargetLanguage:只是对模板代码的一个分类,不会影响生成的代码语言。是模板的一个属性,说明模板要基于那种语言生成相应的代码。例如你可以用CodeSmith从任何一种语言生成C#代码。
Description:对于模板的一些说明信息,在CodeSmith Explorer中选中该模板时会显示这里的信息。
Inherits:所有CodeSmith模板默认继承自CodeSmith.Engine.CodeTemplate,这个类提供模板使用的一些基本功能,像ASP.NET页面的Page类,这些被继承的类的属性可以被修改,但是这些新的类也必须继承CodeSmith.Engine.CodeTemplate。CodeSmith也同样可以找到这个类,当然你要引入一个组件包含这个类。
Src:在某些方面Src和继承Inherits比较相似,它们都允许你从其他的类包含一些功能进模板。这两个属性的区别是,Src可以让类与你的模板被动态编译,而Inherits仅允许你提供一个已经编译好的类或组件。
Debug:可以确定是否在模板中可以包含调试符号。如果将这个属性设置为True,则可以使用System.Diagnostics.Debugger.Break()方法来设置断点。
LinePragmas:设置为True,模板的错误将被指向到模板的源代码。设置为False,模板的错误将被指向到编译的源代码。
属性的声明(Property Directive)
属性被用做在模板运行时声明一个使用的参数,例:
<
%@ Property
Name
="ClassName"
Type
="String"
Default
="Class1"
Category
="Context"
Description
="The name of the class to generate"
Optional
="true"
%
>
属性参数的介绍:
Name:模版使用的参数的名称。
Type:参数类型可以是任何.NET有效的数据类型,例如简单的String类型或者是CodeSmith的SchemaExplorer.DatabaseSchema类型。注意,类型必须是基类库的类型,例如用String或者Int32代替string和int。
Default:设置默认值。
Category:用来说明这个属性在CodeSmith Explorer的属性面板中显示成什么类型,例如下拉选择、直接输入等。
Description:在属性面板中对于这个属性的描述。
Optional:设置这个属性是否是必须的,设置为True表明这个参数值可有可无,设置为False则这个参数必须有值。
Editor:表明在属性面板中输入这个属性的值时使用何种GUI(图形界面编辑器)编辑器。
EditorBase:编辑器使用的基本类型,如果没有被说明,UITypeEditor为默认编辑器。
Serializer:这块我的水平不太会犯疑:)The serializer parameter specifies the IPropertySerializer type to use when serializing the properties values. This is equivalent to using a [PropertySerializerAttribute].
XML属性声明(XmlProperty Directive)
例:
<
%@ XmlProperty
Name
="EntityMap"
Schema
="EntityMap.xsd"
Optional
="False"
Category
="Context"
Description
="EntityMap XML file to base the output on."
%
>
XML属性的参数:
Name:名称。
Schema:这个参数用来指定一个X
SD
文件,创建一个强类型对象模型。如果这个计划被指定,编译器会尝试分析这个X
SD
文件并为这个计划生成一个强类型对象模型,这样可以在模版中使用强类型和智能与XML协同工作。如果这个计划没有被设定,这个参数将为XmlDocument类型并且将使用XML DOM去导航到一个XML内容并生成代码。
Category:在CodeSmith属性面板中的类别。
Description:描述。
Optional:这个参数是否是必须的,如果设置为True,则参数不是必须的,反之False则为必须的。在设置为False时,如果用户没有提供参数则CodeSmith不能继续运行。
注册的声明(Register Directive)
这个属性通常被用作引入另一个模版文件并与当前的模版文件同时被编译。这是一种使用子模版的交互方法。
例:
<
%@ Register
Name
="MySubTemplate"
Template
="MySubTemplate.cst"
MergeProperties
="True"
ExcludeProperties
="SomeExcludedPropertyName,SomeProperties*"
%
>
模版一旦被注册,就可以建立一个模版的实例,然后象这样设置它的属性:
1
<
script runat
=
"
template
"
>
2
public
void
OutputSubTemplate()
3
{
4
MySubTemplate mySubTemplate
=
new
MySubTemplate();
5
6
//
set an individual properties value.
7
mySubTemplate.SomeExcludedPropertyName
=
"
SomeValue
"
;
8
9
//
copy all properties with matching name and type to the sub template instance.
10
this
.CopyPropertiesTo(mySubTemplate);
11
12
//
render the template to the current templates Response object.
13
mySubTemplate.Render(
this
.Response);
14
15
//
render the template to a file.
16
mySubTemplate.RenderToFile(
"
C:\SomeFile.txt
"
);
17
}
18
</
script
>
注册的参数:
Name:代表被引入的模版的名称。它可以被用作创建一个模版的实例。
Template:被引入模版文件的相对路径,它可以与当前的模版一起被动态的编译。
MergeProperties:设置成True时,所有被引用的面板的属性将被动态的添加到当前模版中。
ExcludePorperties:当使用MergeProperties时,你可能不需要某些属性被添加到当前模版中。将不需要的属性以逗号分隔放在这里,*号可以被用作通配符使用。
组件的声明(Assembly Directive)
用作在模版中引用一个外部部组件,或者包含一个编译好的源文件。
例:
<
%@ Assembly
Name
="SchemaExplorer"
%
>
或
<
%@ Assembly
Src
="MySourceFile.cs"
%
>
CodeSmith自动加载一些不同的组件:System, System.Diagnostics, System.ComponentModel, Microsoft.VisualBasic, CodeSmith.Engine
组件的参数:
Name:需要引用组件的名称,组建必须存在于Global Assembly Cache,与CodeSmith在同一路径下或与模版文件在同一路径下。
Src:要包含文件的相对路径。
引入的声明(Import Directive)
在模版中引入一个命名空间,这个与VB.NET中的Imports和C#中的using相同。
例:
<
%@ Import
Namespace
="SchemaExplorer"
%
>
引入的参数:
NameSpace:被引入的命名空间的名字。记住同时必须要加载包含这个命名空间的相应组件,除非这个组件是被默认加载的。
posted @
2006-04-13 16:43 jirong 阅读(259) |
评论 (0) |
编辑
摘要: 这里写的东东都是从CodeSmith自带的帮助文档中FAQ里学到的东东 1.如何在模板中添加注释 CodeSmith: <%--Comments --%> VB.NET: <%--'Comments --%> C#: <%--// Comments --%> <%--/* Comments */ --%> 2.创建一个可以下拉选择的属性 首先定义一个...
阅读全文
posted @
2006-04-13 16:36 jirong 阅读(252) |
评论 (1) |
编辑
本文将介绍CodeSmith与数据库进行交互生成相应的存储过程,本例使用的数据库为SQL Server 2000。
在与数据库进行交互时,我们使用到了一个CodeSmith自带的组件
SchemaExplorer,利用这个组件我们可以访问数据库的数据表、存储过程、视图等,并可以得到相应的数据类型、标识列、列的(字段)名称等信息。
下面这个例子是教我们如何生成一个存储过程,虽然网上有很多一样的例子,但是我是从CodeSmith中的英文帮助中自己翻译出来的:)
使用的是SQL Server 2000自带的Northwind数据库,生成一个关于Orders订单表的更新存储过程。
第一步还是指明模板使用的语言和生成的目标语言。
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="T-SQL"
Description
="Generates a update stored procedure."
%
>
第二步就是我们要加载使用访问数据库的组件SchemaExplorer,并声明其使用的命名空间。
<
%@ Assembly
Name
="SchemaExplorer"
%
>
<
%@ Import
Namespace
="SchemaExplorer"
%
>
因为是针对表去生成存储过程,则首先要定义一个存储表名称使用的变量,然后指明这个变量类型为数据库中的表,这样我们可以通过这个数据表类型的变量得到相应的表的信息。
<
%@ Property
Name
="SourceTable"
Type
="SchemaExplorer.TableSchema"
Category
="Context"
Description
="Table that the stored procedures should be based on."
%
>
如果想访问视图的话,则将变量类型Type中的SchemaExplorer.TableSchema修改为SchemaExplorer.ViewSchema即可。
得到表名的方法
CREATE
PROCEDURE
dbo.
Update
<%=
SourceTable.Name
%>
下面利用循环语句遍历表的各个列,拼出存储过程需要传递的参数。
<%
for
(
int
i
=
0
; i
<
SourceTable.Columns.Count; i
++
) {
%>
<%=
GetSqlParameterStatement(SourceTable.Columns[i])
%><%
if
(i
<
SourceTable.Columns.Count
-
1
) {
%>
,
<%
}
%>
<%
}
%>
调用的GetSqlParameterStatement方法是用来生成参数的字符串,例如生成“@CustomerID nchar(5)”,后边紧跟的if判断是用来生成参数之间相隔使用的逗号的。
生成参数字符串的方法,参数为SchemaExplorer.ColumnSchema列类型
1
<
script runat
=
"
template
"
>
2
public string GetSqlParameterStatement(ColumnSchema column)
3
{
4
string param
=
"
@
"
+
column.Name
+
"
"
+
column.NativeType;
5
6
switch
(column.DataType)
7
{
8
case
DbType.Decimal:
9
{
10
param
+=
"
(
"
+
column.Precision
+
"
,
"
+
column.Scale
+
"
)
"
;
11
break
;
12
}
13
default
:
14
{
15
if
(column.Size
>
0
)
16
{
17
param
+=
"
(
"
+
column.Size
+
"
)
"
;
18
}
19
break
;
20
}
21
}
22
23
return
param;
24
}
25
</
script
>
下面来生成需要更新的字段,更新时仅能更新非主键字段的值,在SchemaExplorer中支持这种区别,使用SourceTable.NonPrimaryKeyColumns即可得到非主键字段的集合。
1
UPDATE
[
<%= SourceTable.Name %>
]
SET
2
<%
for
(
int
i
=
0
; i
<
SourceTable.NonPrimaryKeyColumns.
Count
; i
++
) {
%>
3
[
<%= SourceTable.NonPrimaryKeyColumns[i
]
.Name
%>
]
=
@
<%=
SourceTable.NonPrimaryKeyColumns
[
i
]
.Name
%><%
if
(i
<
SourceTable.NonPrimaryKeyColumns.
Count
-
1
) {
%>
,
<%
}
%>
4
<%
}
%>
然后再使用SourceTable.PrimaryKey.MemberColumns得到数据表中的主键集合,生成更新条件
1
WHERE
2
<%
for
(
int
i
=
0
; i
<
SourceTable.PrimaryKey.MemberColumns.
Count
; i
++
) {
%>
3
<%
if
(i
>
0
) {
%>AND
<%
}
%>
4
[
<%= SourceTable.PrimaryKey.MemberColumns[i
]
.Name
%>
]
=
@
<%=
SourceTable.PrimaryKey.MemberColumns
[
i
]
.Name
%>
5
<%
}
%>
以下为整体的代码结构
1
<
%@ CodeTemplate
Language
="C#"
TargetLanguage
="T-SQL"
2
Description
="Generates a update stored procedure."
%
>
3
4
<
%@ Property
Name
="SourceTable"
Type
="SchemaExplorer.TableSchema"
5
Category
="Context"
6
Description
="Table that the stored procedures should be based on."
%
>
7
8
<
%@ Assembly
Name
="SchemaExplorer"
%
>
9
10
<
%@ Import
Namespace
="SchemaExplorer"
%
>
11
12
<
script
runat
="template"
>
13
public string GetSqlParameterStatement(ColumnSchema column)
14
{
15
string param = "@" + column.Name + " " + column.NativeType;
16
17
switch (column.DataType)
18
{
19
case DbType.Decimal:
20
{
21
param += "(" + column.Precision + ", " + column.Scale + ")";
22
break;
23
}
24
default:
25
{
26
if (column.Size > 0)
27
{
28
param += "(" + column.Size + ")";
29
}
30
break;
31
}
32
}
33
34
return param;
35
}
36
</
script
>
37
38
-----------------------------------------------------------------
39
-- Date Created:
<
%= DateTime
.Now.ToLongDateString() %
>
40
-- Created By: Generated by CodeSmith
41
-----------------------------------------------------------------
42
43
CREATE PROCEDURE dbo.Update
<
%= SourceTable
.Name %
>
44
<
% for
(int i
= 0;
i < SourceTable.Columns.Count; i++) { %
>
45
<
%= GetSqlParameterStatement
(SourceTable.Columns[i]) %
><
% if
(i < SourceTable.Columns.Count - 1) { %
>
,
<
% } %
>
46
<
% } %
>
47
AS
48
49
UPDATE [
<
%= SourceTable
.Name %
>
] SET
50
<
% for
(int i
= 0;
i < SourceTable.NonPrimaryKeyColumns.Count; i++) { %
>
51
[
<
%= SourceTable
.NonPrimaryKeyColumns[i].Name %
>
] = @
<
%= SourceTable
.NonPrimaryKeyColumns[i].Name %
><
% if
(i < SourceTable.NonPrimaryKeyColumns.Count - 1) { %
>
,
<
% } %
>
52
<
% } %
>
53
WHERE
54
<
% for
(int i
= 0;
i < SourceTable.PrimaryKey.MemberColumns.Count; i++) { %
>
55
<
% if
(i
>
0) { %>AND
<
% } %
>
56
[
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
] = @
<
%= SourceTable
.PrimaryKey.MemberColumns[i].Name %
>
57
<
% } %
>
58