首页 > 其他分享 >T4模板使用记录,生成Model、Service、Repository

T4模板使用记录,生成Model、Service、Repository

时间:2024-03-19 09:36:24浏览次数:23  
标签:case Repository Service T4 break commonType csharpType typeof string

自己目前在搭建一个.NET Core的框架,本来是打算使用前端做代码生成器直接生成到文件的,快做好了。感觉好像使用T4更方便一些,所以也就有了这篇文章~ 

我还是有个问题没解决,就是我想生成每个类(接口)单独的文件~,如果有老师知道指点下啊~

在网上找了一篇相关文章 本文也是基于这个做了一下自己的修改。

首先公共程序集创建一个DbHelper.ttinclude

主要就是链接数据库,搜索数据库表及表中字段的信息。

你可以得到这样的结果:瞬间明了了,然后就  爱的魔力转圈圈~ 循环就好了!

代码是这样的:

复制代码
<#+
    public class config
    {
        public static readonly string ConnectionString="Data Source=(local);Integrated Security=true;Initial Catalog=LJDAPP;";
        public static readonly string DbDatabase="LJDAPP"; 
    }
    public class DbHelper
    { 
        
        public static List<DbTable> GetDbTables(string connectionString, string database)
        { 
            string sql = string.Format(@"SELECT
                obj.name tablename,
                schem.name schemname,
                ISNULL(g.value,'') [description],
                idx.rows,
                CAST
                (
                CASE 
                WHEN (SELECT COUNT(1) FROM sys.indexes WHERE object_id= obj.OBJECT_ID AND is_primary_key=1) >=1 THEN 1
                ELSE 0
                END 
                AS BIT) HasPrimaryKey                                         
                from {0}.sys.objects obj 
                inner join {0}.dbo.sysindexes idx on obj.object_id=idx.id and idx.indid<=1
                INNER JOIN {0}.sys.schemas schem ON obj.schema_id=schem.schema_id
                left join {0}.sys.extended_properties g ON (obj.object_id = g.major_id AND g.minor_id = 0 AND g.name= 'MS_Description')
                where type='U' 
                order by obj.name", database); 
            DataTable dt = GetDataTable(connectionString, sql);
            return dt.Rows.Cast<DataRow>().Select(row => new DbTable
                {
                    TableName = row.Field<string>("tablename"),
                    SchemaName = row.Field<string>("schemname"),
                    Description=row.Field<string>("description"),
                    Rows = row.Field<int>("rows"),
                    HasPrimaryKey = row.Field<bool>("HasPrimaryKey")
                    }).ToList();
        }
        
 
        
        public static List<DbColumn> GetDbColumns(string connectionString, string database, string tableName, string schema = "dbo")
        { 
            string sql = string.Format(@"
                WITH indexCTE AS
                (
                SELECT 
                ic.column_id,
                ic.index_column_id,
                ic.object_id    
                FROM {0}.sys.indexes idx
                INNER JOIN {0}.sys.index_columns ic ON idx.index_id = ic.index_id AND idx.object_id = ic.object_id
                WHERE  idx.object_id =OBJECT_ID(@tableName) AND idx.is_primary_key=1
                )
                select
                colm.column_id ColumnID,
                CAST(CASE WHEN indexCTE.column_id IS NULL THEN 0 ELSE 1 END AS BIT) IsPrimaryKey,
                colm.name ColumnName,
                systype.name ColumnType,
                colm.is_identity IsIdentity,
                colm.is_nullable IsNullable,
                cast(colm.max_length as int) ByteLength,
                (
                case 
                when systype.name='nvarchar' and colm.max_length>0 then colm.max_length/2 
                when systype.name='nchar' and colm.max_length>0 then colm.max_length/2
                when systype.name='ntext' and colm.max_length>0 then colm.max_length/2 
                else colm.max_length
                end
                ) CharLength,
                cast(colm.precision as int) Precision,
                cast(colm.scale as int) Scale,
                prop.value Remark
                from {0}.sys.columns colm
                inner join {0}.sys.types systype on colm.system_type_id=systype.system_type_id and colm.user_type_id=systype.user_type_id
                left join {0}.sys.extended_properties prop on colm.object_id=prop.major_id and colm.column_id=prop.minor_id
                LEFT JOIN indexCTE ON colm.column_id=indexCTE.column_id AND colm.object_id=indexCTE.object_id                                        
                where colm.object_id=OBJECT_ID(@tableName)
                order by colm.column_id", database);
            
            SqlParameter param = new SqlParameter("@tableName", SqlDbType.NVarChar, 100) { Value = string.Format("{0}.{1}.{2}", database, schema, tableName) };
            DataTable dt = GetDataTable(connectionString, sql, param);
            return dt.Rows.Cast<DataRow>().Select(row => new DbColumn()
                {
                    ColumnID = row.Field<int>("ColumnID"),
                    IsPrimaryKey = row.Field<bool>("IsPrimaryKey"),
                    ColumnName = row.Field<string>("ColumnName"),
                    ColumnType = row.Field<string>("ColumnType"),
                    IsIdentity = row.Field<bool>("IsIdentity"),
                    IsNullable = row.Field<bool>("IsNullable"),
                    ByteLength = row.Field<int>("ByteLength"),
                    CharLength = row.Field<int>("CharLength"),
                    Scale = row.Field<int>("Scale"),
                    Remark = row["Remark"].ToString()
                    }).ToList();
        }

             

 
        
        public static DataTable GetDataTable(string connectionString, string commandText, params SqlParameter[] parms)
        {
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                SqlCommand command = connection.CreateCommand();
                command.CommandText = commandText;
                command.Parameters.AddRange(parms);
                SqlDataAdapter adapter = new SqlDataAdapter(command);

                DataTable dt = new DataTable();
                adapter.Fill(dt);

                return dt;
            }
        }

        
    }
 
    /// <summary>
    /// 表结构
    /// </summary>
    public sealed class DbTable
    {
        /// <summary>
        /// 表名称
        /// </summary>
        public string TableName { get; set; }
        /// <summary>
        /// 表的架构
        /// </summary>
        public string SchemaName { get; set; }
        /// <summary>
        /// 表的说明
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 表的记录数
        /// </summary>
        public int Rows { get; set; }

        /// <summary>
        /// 是否含有主键
        /// </summary>
        public bool HasPrimaryKey { get; set; }
    }
    
 
    /// <summary>
    /// 表字段结构
    /// </summary>
    public sealed class DbColumn
    {
        /// <summary>
        /// 字段ID
        /// </summary>
        public int ColumnID { get; set; }

        /// <summary>
        /// 是否主键
        /// </summary>
        public bool IsPrimaryKey { get; set; }

        /// <summary>
        /// 字段名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 字段类型
        /// </summary>
        public string ColumnType { get; set; }

        /// <summary>
        /// 数据库类型对应的C#类型
        /// </summary>
        public string CSharpType
        {
            get
            {
                return SqlServerDbTypeMap.MapCsharpType(ColumnType);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public Type CommonType
        {
            get
            {
                return SqlServerDbTypeMap.MapCommonType(ColumnType);
            }
        }

        /// <summary>
        /// 字节长度
        /// </summary>
        public int ByteLength { get; set; }

        /// <summary>
        /// 字符长度
        /// </summary>
        public int CharLength { get; set; }

        /// <summary>
        /// 小数位
        /// </summary>
        public int Scale { get; set; }

        /// <summary>
        /// 是否自增列
        /// </summary>
        public bool IsIdentity { get; set; }

        /// <summary>
        /// 是否允许空
        /// </summary>
        public bool IsNullable { get; set; }

        /// <summary>
        /// 描述
        /// </summary>
        public string Remark { get; set; }
    }
    
 

    public class SqlServerDbTypeMap
    {
        public static string MapCsharpType(string dbtype)
        {
            if (string.IsNullOrEmpty(dbtype)) return dbtype;
            dbtype = dbtype.ToLower();
            string csharpType = "object";
            switch (dbtype)
            {
                case "bigint": csharpType = "long"; break;
                case "binary": csharpType = "byte[]"; break;
                case "bit": csharpType = "bool"; break;
                case "char": csharpType = "string"; break;
                case "date": csharpType = "DateTime"; break;
                case "datetime": csharpType = "DateTime"; break;
                case "datetime2": csharpType = "DateTime"; break;
                case "datetimeoffset": csharpType = "DateTimeOffset"; break;
                case "decimal": csharpType = "decimal"; break;
                case "float": csharpType = "double"; break;
                case "image": csharpType = "byte[]"; break;
                case "int": csharpType = "int"; break;
                case "money": csharpType = "decimal"; break;
                case "nchar": csharpType = "string"; break;
                case "ntext": csharpType = "string"; break;
                case "numeric": csharpType = "decimal"; break;
                case "nvarchar": csharpType = "string"; break;
                case "real": csharpType = "Single"; break;
                case "smalldatetime": csharpType = "DateTime"; break;
                case "smallint": csharpType = "short"; break;
                case "smallmoney": csharpType = "decimal"; break;
                case "sql_variant": csharpType = "object"; break;
                case "sysname": csharpType = "object"; break;
                case "text": csharpType = "string"; break;
                case "time": csharpType = "TimeSpan"; break;
                case "timestamp": csharpType = "byte[]"; break;
                case "tinyint": csharpType = "byte"; break;
                case "uniqueidentifier": csharpType = "Guid"; break;
                case "varbinary": csharpType = "byte[]"; break;
                case "varchar": csharpType = "string"; break;
                case "xml": csharpType = "string"; break;
                default: csharpType = "object"; break;
            }
            return csharpType;
        }
           
        public static Type MapCommonType(string dbtype)
        {
            if (string.IsNullOrEmpty(dbtype)) return Type.Missing.GetType();
            dbtype = dbtype.ToLower();
            Type commonType = typeof(object);
            switch (dbtype)
            {
                case "bigint": commonType = typeof(long); break;
                case "binary": commonType = typeof(byte[]); break;
                case "bit": commonType = typeof(bool); break;
                case "char": commonType = typeof(string); break;
                case "date": commonType = typeof(DateTime); break;
                case "datetime": commonType = typeof(DateTime); break;
                case "datetime2": commonType = typeof(DateTime); break;
                case "datetimeoffset": commonType = typeof(DateTimeOffset); break;
                case "decimal": commonType = typeof(decimal); break;
                case "float": commonType = typeof(double); break;
                case "image": commonType = typeof(byte[]); break;
                case "int": commonType = typeof(int); break;
                case "money": commonType = typeof(decimal); break;
                case "nchar": commonType = typeof(string); break;
                case "ntext": commonType = typeof(string); break;
                case "numeric": commonType = typeof(decimal); break;
                case "nvarchar": commonType = typeof(string); break;
                case "real": commonType = typeof(Single); break;
                case "smalldatetime": commonType = typeof(DateTime); break;
                case "smallint": commonType = typeof(short); break;
                case "smallmoney": commonType = typeof(decimal); break;
                case "sql_variant": commonType = typeof(object); break;
                case "sysname": commonType = typeof(object); break;
                case "text": commonType = typeof(string); break;
                case "time": commonType = typeof(TimeSpan); break;
                case "timestamp": commonType = typeof(byte[]); break;
                case "tinyint": commonType = typeof(byte); break;
                case "uniqueidentifier": commonType = typeof(Guid); break;
                case "varbinary": commonType = typeof(byte[]); break;
                case "varchar": commonType = typeof(string); break;
                case "xml": commonType = typeof(string); break;
                default: commonType = typeof(object); break;
            }
            return commonType;
        }
    }
    
    

#>
复制代码

这个其实也是可以一起放到模板里的,不过因为好几个地方都需要用到,为了修改方便,还是单独拿出来比较好。

使用的时候会用到:

<#@ include file="$(ProjectDir)../LJD.App.Util/T4/DbHelper.ttinclude"  #>

显而易见,我放到了 LJD.App.Util类库下T4文件夹

这里说下T4 程序集指令  还有一篇文章:T4模版引擎之基础入门 是这样说的

<#@ assembly name="[assembly strong name|assembly file name]" #>

 

1、程序集指令相当于VS里面我们添加程序集引用的功能,该指令只有一个参数name,用以指定程序集名称,如果程序集已经在GAC里面注册,那么只需要写上程序集名称即可,如<#@ assembly name="System.Data.dll" #>,否则需要指定程序集的物理路径。

2、T4模版的程序集引用是完全独立的,也就是说我们在项目中引用了一些程序集,然后项目中添加了一个T4模版,T4模版所需要的所有程序集引用必须明确的在模版中使用程序集执行引用才可以。

3、T4模版自动加载以下程序集Microsoft.VisualStudio.TextTemplating.1*.dll、System.dll、WindowsBase.dll,如果用到了其它的程序集需要显示的使用程序集添加引用才可以

4、可以使用 $(variableName) 语法引用 Visual Studio 或 MSBuild 变量(如 $(SolutionDir)),以及使用 %VariableName% 来引用环境变量。介绍几个常用的$(variableName) 变量:

    $(SolutionDir):当前项目所在解决方案目录

    $(ProjectDir):当前项目所在目录

    $(TargetPath):当前项目编译输出文件绝对路径

    $(TargetDir):当前项目编译输出目录,即web项目的Bin目录,控制台、类库项目bin目录下的debug或release目录(取决于当前的编译模式)

    举个例子:比如我们在D盘根目录建立了一个控制台项目TestConsole,解决方案目录为D:\LzrabbitRabbit,项目目录为
    D:\LzrabbitRabbit\TestConsole,那么此时在Debug编译模式下
    $(SolutionDir)的值为D:\LzrabbitRabbit
    $(ProjectDir)的值为D:\LzrabbitRabbit\TestConsole
    $(TargetPath)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\TestConsole.exe
    $(TargetDir)值为D:\LzrabbitRabbit\TestConsole\bin\Debug\

好了,准备工作都做完了,要创建T4模板了,这个还要图吗?

然后贴上这段代码,在foreach中发挥你的想想吧!对了,要注意命名空间和using哈~

复制代码
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Data.DataSetExtensions" #>
<#@ assembly name="System.Xml" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ include file="$(ProjectDir)../LJD.App.Util/T4/DbHelper.ttinclude"  #>
//------------------------------------------------------------------------------
// <auto-generated>
//     此代码由T4模板自动生成
//     生成时间 <#=        DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")#> by Jelly
//     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using LJD.App.Model.DbModels;

namespace LJD.App.Repository.IRepository
{
 <#    foreach(DbTable table in DbHelper.GetDbTables(config.ConnectionString, config.DbDatabase)){#> 
<#        if(table.TableName!="Base") {#>
        /// <summary>
        /// <#=table.Description#>
        /// </summary>        
        public partial interface I<#=table.TableName#>Repository : IBaseRepository<<#=table.TableName#>>
        {

        }
<#} #>
        <#     }#> 
}  
复制代码

标签:case,Repository,Service,T4,break,commonType,csharpType,typeof,string
From: https://www.cnblogs.com/Alex80/p/18082035

相关文章

  • 【App Service】在Azure App Service中分析.NET应用程序的性能的好帮手(Review Stack
    AzureAppService.NETProfiler在AppService服务中,如果部署了.NET应用,平台有一个非常好的工具可以查看请求的性能分布及异常时的StackTraces。进入路径:AppServiceAzureOverview-->  Networking(网络)-->Troubleshoot(排除故障)--> Collect.NETProfilerTrace......
  • 急速搭建ChatGPT——GPT4All本地部署
    云服务器可至雨云进行购买首先打开雨云官网雨云官网网址:https://www.rainyun.com/YZJ_?s=xxx 然后登录/注册雨云(登录/注册建在右上角)  如果没注册就点击下方注册,然后如果显示“正在使用优惠通道注册”就照常输入信息 没有则优惠码填“YZJ” 推荐配......
  • Azure REST API (5) Azure创建Service Principal设置Client Secret过期时间100年
    《WindowsAzurePlatform系列文章目录》 我们在使用AzureServicePrinciple,通过应用程序开发API方式部署或修改Azure资源的时候,默认的ClientSecret过期时间为2年。很多客户希望ClientSecret过期时间大于2年。我们可以通过使用应用管理策略(AppManagem......
  • service层设置手动事务回滚,原因@Transactional事务与try{}catch(){}会失效,导事务不回
     1、原因是这样的,在service层的方法中,需要执行多条update或insert的数据操作,service的方法上是加@Transactional(rollbackFor=Exception.class)注解,然后方法体中又用了try{}catch(){}操作,导致在update多个执行时,其中有一条sql报错,本应该执行事务回滚操作报错前的update都不应......
  • spring boot使用MongoRepository简单的CRUD
    简单的CRUD首先,定义一个实体类,例如User:@DocumentpublicclassUser{@IdprivateStringid;privateStringname;privateintage;//构造函数、getter和setter省略...}接下来,定义一个继承自MongoRepository的接口,例如UserRepository:publicint......
  • spring boot使用MongoRepository更新单个字段
    在SpringDataMongoDB中,MongoRepository接口提供了基本的CRUD操作。如果你想要通过MongoRepository更新单个字段,你可以自定义一个更新方法或者使用内置的save()方法。这里是一个示例:假设你有一个名为User的实体类,并且有一个继承自MongoRepository的UserRepository接口://定义Us......
  • OpenAI反击!GPT4.5 拟本周发布,Claude3将再次被打回备胎!Sora会上线吗?
     ChatGPT狂飙160天,世界已经不是之前的样子。新建了人工智能中文站https://ai.weoknow.com每天给大家更新可用的国内可用chatGPT资源 发布在https://it.weoknow.com 它来了,它来了,GPT4.5真的来了!官方已经把GPT4.5的网页都做好了!当你使用「DuckDuckGo」搜索“”G......
  • 猫头虎分享已解决Bug || 服务版本冲突(Service Version Conflict):VersionMismatchError,
    博主猫头虎的技术世界......
  • 国内GPT4.0升级支付宝充值流程,2024年3月9日最新教程
    前言最近,有很多中国用户在充值ChatGPTPLUS会员的时候,会收到如下提示:您的信用卡被拒绝了。请尝试使用借记卡支付。这可能是由于多种原因导致的,例如:信息填写错误,信用卡已过期、信用额度不足、卡片被冻结等等各种原因。首先,需要确定的是,你是不是用的国内的信用卡?目前所有国内开......
  • ext4 子目录数量验证
    ext4子目录数量验证背景最近同事问到一个问题。信创linux系统是否默认是ext4的文件系统。我这边一般是使用iso自行安装,文件系统一般是选择xfs后者是ext4最近安装系统使用ext4比较多一些。然后突然又问到是不是ext4有一个最大子目录64000的限制。我当时有点懵,感......