CodeSmith(4):创建实体类实例

利用SchemaExplorer中的类:TableSchemaColumnSchema来制造一个实体类。

 首先我们得了解实体类的构成,一般的实体类由私有字段和公开方法组成,例如下面的类:

using System;

using System.Collections.Generic;

using System.Text;

 

namespace com.xaccp.Entity

{

    public class Person

    {

        private string name;

        private bool sex;

        private int age;

        public string Name

        {

            get { return name; }

            set { name = value; }

        }

,,,,,

    }

}

 

实体类中的字段应该和数据库中的字段相同,只是类型要从Sql中的数据类型变为C#中的数据类型,一般实体类中的字段的名字可以采用与数据库中字段的名称相同,只不过字段名一般采用骆驼命名法,属性名称一般采用Pascal命名法。

 

私有字段部分有些内容是永远不变的,字段的访问修饰符永远为private,字段的结尾永远为;;变化的部分为,每个字段根据数据库中的类型变化为C#中的类型,字段的名称也是变化的。

 

公开字段中也有内容为永远不变的

 public 数据类型 属性名称

        {

            get { return 字段名称; }

            set { 字段名称 = value; }

        }

 

 

第一个模板

<%@ CodeTemplate Language="C#" TargetLanguage="C#" Src="" Inherits="" Debug="False" Description="产生实体类" ResponseEncoding="UTF-8" %>

<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Default="" Optional="False" Category="Context" Description="源表名" %>

<%@ Assembly Name="SchemaExplorer" %>

<%@ Import Namespace="SchemaExplorer" %>

<%@ Assembly Name="System.Data" %>

<%@ Import Namespace="System.Data" %>

 

using System;

namespace com.xaccp.Entity

{

    public class Person

    {

        //这里的内容为私有字段和公开属性。

 <%foreach(ColumnSchema column in this.SourceTable.Columns)%>

 <%{%>

 private <%=column.SystemType%> <%=column.Name%>;

 <%}%>

 <%foreach(ColumnSchema column in this.SourceTable.Columns)%>

 <%{%>

 public <%=column.SystemType%> <%=column.Name%>

 {

   get{return <%=column.Name%>;}

   set{<%=column.Name%>=value;}

 }

 <%}%>

    }

}

 

所产生的实体类问题?

第一:所产生的这个类,根本编译不过去。

第二:这个类的类名永远是Person,即使产生了这个类,还得修改。

第三:命名空间也要改。

第四:……

 

错误提示在title_id这个属性那里。原来是字段名称和属性名称冲突了,正确的应该是字段名称使用骆驼命名法,而属性用Pascal命名法。只需要将字段的第一个字母改为小写,属性的第一个字母改为大写。

 

写一个公共函数

//以骆驼命名法格式化字符串

public string ToCamel(string s)

{

       return s.Substring(0,1).ToLower()+s.Substring(1);

}

 

//Pascal命名法格式化字符串

public string ToPascal(string s)

{

       return s.Substring(0,1).ToUpper()+s.Substring(1);

}

 

更改输出的代码段:

//字段部分

private <%=column.SystemType%> <%=ToCamel(column.Name)%>;

//属性部分

public <%=column.SystemType%> <%=ToPascal(column.Name)%>

{

       get{return <%=ToCamel(column.Name)%>;}

       get{<%=ToCamel(column.Name)%>=value;}

}

 

类名变化

最好让类名和表名有关系。表名能不能来做类名呢?因为表名通常为复数形式,能不能改成单数啊?只要去掉表名后的“s”

public string GetClassName(TableSchema table)

{

       string s=table.Name;

       if(s.Substring(s.Length-1)=="s")

       {

              return ToPascal(s.Substring(0,s.Length-1));

       }

       return ToPascal(s);

}

 

class <%=GetClassName(this.SourceTable)%>

 

命名空间

一般情况下,都将命名空间设置为Model或者Entity,可是到底选择哪一个什么?

在声明部分添加:

<%@ Property Name="NameSpace" Type="System.String" Default="Model" Optional="False" Category="" Description="" Editor="" EditorBase="" Serializer="" %>

namespace <%=NameSpace%>

 

类型问题

private <%=column.SystemType%> <%=ToCamel(column.Name)%>;

“System.String”“string”都是一回事,我们写的程序毕竟不是用MSIL语言写的,是用C#,最好别用CTS中的数据类型?

 

解决的函数如下:

public string GetCSDataType(ColumnSchema column)

{

       switch (column.DataType)

       {

              case DbType.AnsiString: return "string";

              case DbType.AnsiStringFixedLength: return "string";

              case DbType.Binary: return "byte[]";

              case DbType.Boolean: return "bool";

              case DbType.Byte: return "byte";

              case DbType.Currency: return "decimal";

              case DbType.Date: return "DateTime";

              case DbType.DateTime: return "DateTime";

              case DbType.Decimal: return "decimal";

              case DbType.Double: return "double";

              case DbType.Guid: return "Guid";

              case DbType.Int16: return "short";

              case DbType.Int32: return "int";

              case DbType.Int64: return "long";

              case DbType.Object: return "object";

              case DbType.SByte: return "sbyte";

              case DbType.Single: return "float";

              case DbType.String: return "string";

              case DbType.StringFixedLength: return "string";

              case DbType.Time: return "TimeSpan";

              case DbType.UInt16: return "ushort";

              case DbType.UInt32: return "uint";

              case DbType.UInt64: return "ulong";

              case DbType.VarNumeric: return "decimal";

              default:

              {

                     return "__UNKNOWN__" + column.NativeType;

              }

       }

}

 

无论是从列结构上获取的SystemType还是DataType属性,都是用来表达这个列的数据类型的,尽管他们分别是CTSSQL中的数据类型,从CTS转换和从SQL转换,有什么本质差别不?可是DataType是个枚举类型的属性,如果在VS.Net2005中,一旦switch一个枚举变量,可以自动生成这个枚举类型中所有的枚举值的case分支,这样,咱们只需要填写case的结构就可以了。

 

 

 

 

posted @ 2008-10-13 10:23  Astar  阅读(778)  评论(1编辑  收藏  举报