代码改变世界

分享改进 完全定制自己的代码生成器

  熬夜的虫子  阅读(4289)  评论(15编辑  收藏  举报

codesmith确实是款不错的工具 但是它并不开源 对于一些有自己特殊需求的用户只能自己另想其他解决方案 例如我说想做一个web版本的代码生成器或者说用户没有c#基础

这里开源一个之前做过的工具 当初的目的主要是解决在框架当中局部更新的问题
因为在大部分orm框架当中都是简单的获取一个实体 然后这个实体某个值 然后更新的时候 还是传入这个改变的实体 不过严格意义上来说 在你传入更新实体的时候 它的其他字段说不定已经被其他请求更新过了 所以导致你的这次更新会覆盖掉别人的更新 当然也会有同一字段的问题 不过这里不深入讨论该问题 重点在代码生成上

另外一个意义 就是让大家了解一下一般的代码生成器的工作流程以及实现方法


Github地址 https://github.com/dubing/CodePorter

使用方法很简单 先输入数据库连接字符串 下面会出现table和view,当然自己可以根据源代码加载更多的内容

我程序里主要生成实体层和数据处理层所以我提供了2个文本框 一个是实体层的命名空间 一个是数据处理层的命名的命名空间,这样就不用在模板里设置,可以在win界面或者web界面直接修改

选择好表和view并且设置好命名空间后点击启动 左下角提示成功后就可以打开目录 查看自己生成的文件

生成的实体文件

这里的PartiallyColumnAttribute主要就是用来解决局部更新问题,和代码生成本身无关联。

DA文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//------------------------------------
//用途:表LitespeedActivity的数据处理类(工具自动生成)
//作者:杜兵
//时间:2015-03-11 05:43:32
//-------------------------------------
 
using System;
using System.Data;
using System.Data.Common;
using Model.Service;
using Ctrip.TMPay.Framework.Common;
using Ctrip.TMPay.DataAccess.Common;
 
namespace DataAccess.Service
{
    public partial class LitespeedActivityDA : BaseDA<LitespeedActivityDA>
    {
         
        /// <summary>
        /// 根据主键获取LitespeedActivity
        ///</summary>
        ///< param name="serverName"></param>
        ///< returns></returns>
        public LitespeedActivityEntity GetLitespeedActivity(String serverName)
        {
            DbCommand dbCmd = DbObject.GetSqlStringCommand(SqlCommandConstants.LitespeedActivitySelectCommand);
            DbObject.AddInParameter(dbCmd, "@ServerName", DbType.String, serverName);
            LitespeedActivityEntity litespeedActivityEntity = null;
            using (IDataReader dataReader = DbObject.ExecuteReader(dbCmd))
            {
                if (dataReader.Read())
                {
                      litespeedActivityEntity = new LitespeedActivityEntity{
                          ServerName = DbFieldHelper.GetString(dataReader, "ServerName"),
                          ActivityID = DbFieldHelper.GetInt32(dataReader, "ActivityID"),
                          DatabaseID = DbFieldHelper.GetInt32(dataReader, "DatabaseID"),
                          ActivityTypeID = DbFieldHelper.GetInt32(dataReader, "ActivityTypeID"),
                          StartTime = DbFieldHelper.GetDateTime(dataReader, "StartTime"),
                          FinishTime = DbFieldHelper.GetDateTime(dataReader, "FinishTime"),
                          StatusTypeID = DbFieldHelper.GetInt32(dataReader, "StatusTypeID"),
                          DatabaseSize = DbFieldHelper.GetDouble(dataReader, "DatabaseSize"),
                          PercentCompleted = DbFieldHelper.GetInt32(dataReader, "PercentCompleted"),
                          ActivityDetail = DbFieldHelper.GetString(dataReader, "ActivityDetail"),
                          ErrorMessage = DbFieldHelper.GetString(dataReader, "ErrorMessage"),
                          ResultMessage = DbFieldHelper.GetString(dataReader, "ResultMessage"),
                          ReplicateID = DbFieldHelper.GetGuid(dataReader, "ReplicateID"),
                          LS = DbFieldHelper.GetByte(dataReader, "LS"),
                          PID = DbFieldHelper.GetInt32(dataReader, "PID"),
                          NativeSize = DbFieldHelper.GetDouble(dataReader, "NativeSize"),
                          BackupSize = DbFieldHelper.GetDouble(dataReader, "BackupSize"),
                          BackupTime = DbFieldHelper.GetDouble(dataReader, "BackupTime"),
                          AttachedNativeSize = DbFieldHelper.GetDouble(dataReader, "AttachedNativeSize"),
                          AttachedBackupSize = DbFieldHelper.GetDouble(dataReader, "AttachedBackupSize"),
                          AttachedBackupTime = DbFieldHelper.GetDouble(dataReader, "AttachedBackupTime"),
                           
                      };
                 }
             }
             return litespeedActivityEntity;
         }  
 
        /// <summary>
        /// 根据主键获取LitespeedActivity
        ///</summary>
        ///< param name="activityID"></param>
        ///< returns></returns>
        public LitespeedActivityEntity GetLitespeedActivity(Int32 activityID)
        {
            DbCommand dbCmd = DbObject.GetSqlStringCommand(SqlCommandConstants.LitespeedActivitySelectCommand);
            DbObject.AddInParameter(dbCmd, "@ActivityID", DbType.Int32, activityID);
            LitespeedActivityEntity litespeedActivityEntity = null;
            using (IDataReader dataReader = DbObject.ExecuteReader(dbCmd))
            {
                if (dataReader.Read())
                {
                      litespeedActivityEntity = new LitespeedActivityEntity{
                          ServerName = DbFieldHelper.GetString(dataReader, "ServerName"),
                          ActivityID = DbFieldHelper.GetInt32(dataReader, "ActivityID"),
                          DatabaseID = DbFieldHelper.GetInt32(dataReader, "DatabaseID"),
                          ActivityTypeID = DbFieldHelper.GetInt32(dataReader, "ActivityTypeID"),
                          StartTime = DbFieldHelper.GetDateTime(dataReader, "StartTime"),
                          FinishTime = DbFieldHelper.GetDateTime(dataReader, "FinishTime"),
                          StatusTypeID = DbFieldHelper.GetInt32(dataReader, "StatusTypeID"),
                          DatabaseSize = DbFieldHelper.GetDouble(dataReader, "DatabaseSize"),
                          PercentCompleted = DbFieldHelper.GetInt32(dataReader, "PercentCompleted"),
                          ActivityDetail = DbFieldHelper.GetString(dataReader, "ActivityDetail"),
                          ErrorMessage = DbFieldHelper.GetString(dataReader, "ErrorMessage"),
                          ResultMessage = DbFieldHelper.GetString(dataReader, "ResultMessage"),
                          ReplicateID = DbFieldHelper.GetGuid(dataReader, "ReplicateID"),
                          LS = DbFieldHelper.GetByte(dataReader, "LS"),
                          PID = DbFieldHelper.GetInt32(dataReader, "PID"),
                          NativeSize = DbFieldHelper.GetDouble(dataReader, "NativeSize"),
                          BackupSize = DbFieldHelper.GetDouble(dataReader, "BackupSize"),
                          BackupTime = DbFieldHelper.GetDouble(dataReader, "BackupTime"),
                          AttachedNativeSize = DbFieldHelper.GetDouble(dataReader, "AttachedNativeSize"),
                          AttachedBackupSize = DbFieldHelper.GetDouble(dataReader, "AttachedBackupSize"),
                          AttachedBackupTime = DbFieldHelper.GetDouble(dataReader, "AttachedBackupTime"),
                           
                      };
                 }
             }
             return litespeedActivityEntity;
         }  
 
        /// <summary>
        /// 全参数更新LitespeedActivity
        ///</summary>
        ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
        ///< returns></returns>
        public BizResult<string> UpdateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
        {
            FillParams(litespeedActivityEntity);
            return PartiallyUpdateLitespeedActivity(litespeedActivityEntity);
        }   
 
        /// <summary>
        /// 部分参数更新LitespeedActivity
        ///</summary>
        ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
        ///< returns></returns>
        public BizResult<string> PartiallyUpdateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
        {             
             return ExecuteSP(SqlProcedureConstants.LitespeedActivityUpdateSpName, CheckUpdate, litespeedActivityEntity);
        }  
         
        /// <summary>
        /// 创建LitespeedActivity
        ///</summary>
        ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
        ///< returns></returns>
        public BizResult<string> CreateLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
        {
             FillParams(litespeedActivityEntity);
             return ExecuteSP(SqlProcedureConstants.LitespeedActivityInsertSpName, null, litespeedActivityEntity);
        
         
        /// <summary>
        /// 删除LitespeedActivity
        ///</summary>
        ///< param name="litespeedActivityEntity">LitespeedActivityEntity</param>
        ///< returns></returns>
        public BizResult<string> DeleteLitespeedActivity(LitespeedActivityEntity litespeedActivityEntity)
        {
             FillPKParams(litespeedActivityEntity);
             return ExecuteSP(SqlProcedureConstants.LitespeedActivityDeleteSpName, null, litespeedActivityEntity);
        
   }
}

还有其他的一些文件就不一一列出了

原理很简单 也是根据模板。不过和codesmith不同的是 我这里用的是xsl模板包括语法

基于xml的语法并不难 就算不懂.net的人学习半个小时也可以自己定制模板了

举个例子

复制代码
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="utf-8" method="text" indent="no"/>
  <xsl:variable name="BaseName" select="/DocumentElement/@BaseName"/>
  <xsl:variable name="BaseDbObject" select="/DocumentElement/@BaseDbObject"/>
  <xsl:variable name="DefaultNamespace" select="/DocumentElement/@DefaultNamespace"/>
  <xsl:variable name="DateTime" select="/DocumentElement/@DateTime"/>
  <xsl:variable name="SchemaTable" select="/DocumentElement/SchemaTable[translate(IsHidden,'TRUE','true')!='true']"/>
  <xsl:variable name="TableClassName">
    <xsl:value-of select="$BaseName"/>Table
  </xsl:variable>
  <xsl:template match="/">    //------------------------------------
    //用途:表<xsl:value-of select="$BaseDbObject"/>的实体类(工具自动生成)
    //作者:杜兵 
    //时间:<xsl:value-of select="$DateTime"/>
    //-------------------------------------

    using System;
    using System.Data;

    namespace <xsl:value-of select="$DefaultNamespace"/>
    {
        [Serializable]
        public partial class <xsl:value-of select="$BaseName"/>Entity : BaseEntity
        {<xsl:for-each select="$SchemaTable">  
          <xsl:variable name="PublicPropertyName">
            <xsl:value-of select="PropertyName"/>
          </xsl:variable>    
          <xsl:variable name="ShortDataType">
            <xsl:choose>
              <xsl:when test="ProviderDataType='System.Data.SqlTypes.SqlXml'">System.Xml.Linq.XElement</xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="ShortDataType"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="DbDataType">
            <xsl:choose>
              <xsl:when test="ProviderTypeName='SqlDbType.Timestamp'">rowversion</xsl:when>
              <xsl:when test="ProviderTypeName='SqlDbType.Variant'">Variant</xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="DataTypeFullName"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:variable>
          <xsl:variable name="Description">
            <xsl:value-of select="Description"/>
          </xsl:variable><xsl:variable name="DbType">
          <xsl:value-of select="DBDataTypeFullName"/>
        </xsl:variable>
          /// <summary>
          /// <xsl:value-of select="$Description"/>
          ///</summary>       
          [PartiallyColumnAttribute(DbType = <xsl:value-of select="$DbType"/> <xsl:choose><xsl:when test="AllowDBNull='false'">, CanBeNull = false</xsl:when><xsl:otherwise>, CanBeNull = true</xsl:otherwise></xsl:choose><xsl:if test="IsKey='true'">, IsPrimaryKey = true</xsl:if>)]
          public <xsl:value-of select="$ShortDataType"/><xsl:text> </xsl:text><xsl:value-of select="$PublicPropertyName"/> {  get; set; }</xsl:for-each> 
        }
    }
  </xsl:template>
</xsl:stylesheet>
复制代码

  这里代码里模板实现主要是解决局部更新的功能,大家可以根据自己不同的需求来修改部分逻辑。

  核心的配置文件在config下CodeSet.xml

  主要的配置节点如下

复制代码
  <generatorSettings>
    <ConstantsGenerator>
      <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
      <add key="XslTemplate" value="CodePorter.Templates.SqlConstantsTemplate.xsl"/>
      <add key="TargetFile" value=".\Repository\SqlConstants.cs"/>
      <add key="BeginRegion" value="#region select command,#region sp name"/>
      <add key="EndRegion" value="#endregion,#endregion"/>
    </ConstantsGenerator>
    <BaseDbEntityGenerator>
      <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
      <add key="XslTemplate" value="CodePorter.Templates.BaseDbEntityTemplate.xsl"/>
      <add key="TargetFile" value=".\Entity\BaseEntity.cs"/>
    </BaseDbEntityGenerator>
    <DbEntityGenerator>
      <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
      <add key="XslTemplate" value="CodePorter.Templates.DbEntityTemplate.xsl"/>
      <add key="TargetFile" value=".\Entity\%BASENAME%Entity.cs"/>
    </DbEntityGenerator>
    <BaseDAGenerator>
      <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
      <add key="XslTemplate" value="CodePorter.Templates.BaseDATemplate.xsl"/>
      <add key="TargetFile" value=".\Repository\BaseDA.cs"/>
    </BaseDAGenerator>
    <DAGenerator>
      <add key="DataSourceType" value="CodePorter.Core.DbTableSource"/>
      <add key="XslTemplate" value="CodePorter.Templates.DATemplate.xsl"/>
      <add key="TargetFile" value=".\Repository\%BASENAME%DA.cs"/>
    </DAGenerator>
  </generatorSettings>
复制代码

  细节比较多,但是通过源代码大家应该理解都没有问题,如果有不清楚的地方可以给我留言。后续会放出更多以前做过的工具。


 希望对大家有帮助。

 

努力加载评论中...
点击右上角即可分享
微信分享提示