分享改進 徹底定製本身的代碼生成器

codesmith確實是款不錯的工具 可是它並不開源 對於一些有本身特殊需求的用戶只能本身另想其餘解決方案 例如我說想作一個web版本的代碼生成器或者說用戶沒有c#基礎git

這裏開源一個以前作過的工具 當初的目的主要是解決在框架當中局部更新的問題
由於在大部分orm框架當中都是簡單的獲取一個實體 而後這個實體某個值 而後更新的時候 仍是傳入這個改變的實體 不過嚴格意義上來講 在你傳入更新實體的時候 它的其餘字段說不定已經被其餘請求更新過了 因此致使你的此次更新會覆蓋掉別人的更新 固然也會有同一字段的問題 不過這裏不深刻討論該問題 重點在代碼生成上github

另一個意義 就是讓你們瞭解一下通常的代碼生成器的工做流程以及實現方法web


Github地址 https://github.com/dubing/CodePorter數據庫

使用方法很簡單 先輸入數據庫鏈接字符串 下面會出現table和view,固然本身能夠根據源代碼加載更多的內容c#

我程序裏主要生成實體層和數據處理層因此我提供了2個文本框 一個是實體層的命名空間 一個是數據處理層的命名的命名空間,這樣就不用在模板裏設置,能夠在win界面或者web界面直接修改框架

選擇好表和view而且設置好命名空間後點擊啓動 左下角提示成功後就能夠打開目錄 查看本身生成的文件ide

生成的實體文件工具

這裏的PartiallyColumnAttribute主要就是用來解決局部更新問題,和代碼生成自己無關聯。學習

DA文件ui

    //------------------------------------
    //用途:表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>

  細節比較多,可是經過源代碼你們應該理解都沒有問題,若是有不清楚的地方能夠給我留言。後續會放出更多之前作過的工具。


 但願對你們有幫助。

相關文章
相關標籤/搜索