zoukankan      html  css  js  c++  java
  • T4生成整理

    将一些公用的东西弄到一个类库DM.T4里面,哪个项目需要用到t4生成的话,将DM.T4的生成事件中将dll和ModelAuto.ttinclude复制到需要使用T4的项目的生成目录下,如果这样

    copy $(TargetPath) $(SolutionDir)DM.Domain$(OutDir)
    copy $(TargetDir)ModelAuto.ttinclude $(SolutionDir)DM.Domain$(OutDir)

    然后在需要就可以添加T4文件了,T4文件头部引入即可,例如下面的这个例子,就是根据表生成一些类

    <#@ template debug="true" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    <#@ assembly name="System.Data" #>
    <#@ assembly name="System.Xml" #>
    <#@ assembly name="$(TargetDir)DM.T4.dll"#>
    <#@ import namespace="System" #>
    <#@ import namespace="System.Xml" #>
    <#@ import namespace="System.Data" #>
    <#@ import namespace="System.Data.SqlClient" #>
    <#@ import namespace="System.Collections.Generic"#>
    <#@ import namespace="System.Text.RegularExpressions"#>
    <#@ import namespace="DM.T4"#>
    <#@ include file="$(TargetDir)ModelAuto.ttinclude"#>
    <#    var manager2 = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile)}; #>
    <# 
        ModelManager manager = new ModelManager();
        List<string> list=manager.GetTableList();
        foreach (var item in list)
        {
            string tableName=item;
            DataTable table= manager.GetTableSchema(tableName);
            string strTableMemo=string.Empty;
            if(table!=null&&table.Rows.Count>0)
            {
                strTableMemo=table.Rows[0]["表说明"].ToString();
            }
            manager2.StartBlock(tableName+"Repository.cs");
     #>
    //------------------------------------------------------------------------------
    // <auto-generated>
    //     此代码从T4模板生成。
    //     黄正辉(623128629@qq.com)
    //     手动更改此文件可能导致应用程序出现意外的行为。
    //     如果重新生成代码,将覆盖对此文件的手动更改。
    // </auto-generated>
    //------------------------------------------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Linq.Expressions;
    using System.Data.Common;
    using DM.Domain;
    using DM.Tools;
    using DM.Interface;
    using DM.Interface.IRepository;
    
    namespace DM.Repository.BusinessRepository
    {
        /// <summary>
        /// 仓储实现:<#= strTableMemo #> (<#= tableName #>)
        /// </summary>
        public partial class <#=tableName #>Repository :RepositoryBase<<#=tableName #>>,  I<#=tableName #>Repository,IDependency
        {
            /// <summary>
            /// 插入一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Insert(<#=tableName #> entity)
            {
                return base.Insert(entity);
            }
            /// <summary>
            /// 插入一个数据列表
            /// </summary>
            /// <param name="entity">实体列表</param>
            /// <returns>受影响行数</returns>
            public virtual int Insert(List<<#=tableName #>> entitys)
            {
                return base.Insert(entitys);
            }
            /// <summary>
            /// 修改一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Update(<#=tableName #> entity)
            {
                return base.Update(entity);
            }
            /// <summary>
            /// 删除一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Delete(<#=tableName #> entity)
            {
                return base.Delete(entity);
            }
            /// <summary>
            /// 根据表达式删除
            /// </summary>
            /// <param name="predicate">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Delete(Expression<Func<<#=tableName #>, bool>> predicate)
            {
                return base.Delete(predicate);
            }
            /// <summary>
            /// 根据主键查询一个数据
            /// </summary>
            /// <param name="keyValue">主键值</param>
            /// <returns>实体</returns>
            public virtual <#=tableName #> FindEntity(object keyValue)
            {
                return base.FindEntity(keyValue);
            }
            /// <summary>
            /// 根据表达式查询一个数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <returns>实体</returns>
            public virtual <#=tableName #> FindEntity(Expression<Func<<#=tableName #>, bool>> predicate)
            {
                return base.FindEntity(predicate);
            }
            /// <summary>
            /// 查询IQueryable列表
            /// </summary>
            /// <returns>IQueryable列表</returns>
            public virtual IQueryable<<#=tableName #>> IQueryable()
            {
                return base.IQueryable();
            }
            /// <summary>
            /// 根据表达式查询IQueryable列表数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <returns>IQueryable列表</returns>
            public virtual IQueryable<<#=tableName #>> IQueryable(Expression<Func<<#=tableName #>, bool>> predicate)
            {
                return base.IQueryable(predicate);
            }
            /// <summary>
            /// 根据Sql查询数据
            /// </summary>
            /// <param name="strSql">Sql</param>
            /// <returns>数据列表</returns>
            public virtual List<<#=tableName #>> FindList(string strSql)
            {
                return base.FindList(strSql);
            }
            /// <summary>
            /// 根据Sql查询数据
            /// </summary>
            /// <param name="strSql">Sql</param>
            /// <param name="dbParameter">参数列表</param>
            /// <returns>数据列表</returns>
            public virtual List<<#=tableName #>> FindList(string strSql, DbParameter[] dbParameter)
            {
                return base.FindList(strSql,dbParameter);
            }
            /// <summary>
            /// 查询分页数据
            /// </summary>
            /// <param name="pagination">分页参数</param>
            /// <returns>数据列表</returns>
            public virtual List<<#=tableName #>> FindList(Pagination pagination)
            {
                return base.FindList(pagination);
            }
            /// <summary>
            /// 查询表达式查询分页数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <param name="pagination">分页参数</param>
            /// <returns>数据列表</returns>
            public virtual List<<#=tableName #>> FindList(Expression<Func<<#=tableName #>, bool>> predicate, Pagination pagination)
            {
                return base.FindList(predicate,pagination);
            }
        }
    }
    <#        
     
            manager2.EndBlock(); 
        }
        manager2.Process(true);
    #>
    View Code

    生成后的结果是这样的

    文件的内容如下

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     此代码从T4模板生成。
    //     黄正辉(623128629@qq.com)
    //     手动更改此文件可能导致应用程序出现意外的行为。
    //     如果重新生成代码,将覆盖对此文件的手动更改。
    // </auto-generated>
    //------------------------------------------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Linq.Expressions;
    using System.Data.Common;
    using DM.Domain;
    using DM.Tools;
    using DM.Interface;
    using DM.Interface.IRepository;
    
    namespace DM.Repository.BusinessRepository
    {
        /// <summary>
        /// 仓储实现: (Sys_Role)
        /// </summary>
        public partial class Sys_RoleRepository :RepositoryBase<Sys_Role>,  ISys_RoleRepository,IDependency
        {
            /// <summary>
            /// 插入一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Insert(Sys_Role entity)
            {
                return base.Insert(entity);
            }
            /// <summary>
            /// 插入一个数据列表
            /// </summary>
            /// <param name="entity">实体列表</param>
            /// <returns>受影响行数</returns>
            public virtual int Insert(List<Sys_Role> entitys)
            {
                return base.Insert(entitys);
            }
            /// <summary>
            /// 修改一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Update(Sys_Role entity)
            {
                return base.Update(entity);
            }
            /// <summary>
            /// 删除一个数据
            /// </summary>
            /// <param name="entity">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Delete(Sys_Role entity)
            {
                return base.Delete(entity);
            }
            /// <summary>
            /// 根据表达式删除
            /// </summary>
            /// <param name="predicate">实体</param>
            /// <returns>受影响行数</returns>
            public virtual int Delete(Expression<Func<Sys_Role, bool>> predicate)
            {
                return base.Delete(predicate);
            }
            /// <summary>
            /// 根据主键查询一个数据
            /// </summary>
            /// <param name="keyValue">主键值</param>
            /// <returns>实体</returns>
            public virtual Sys_Role FindEntity(object keyValue)
            {
                return base.FindEntity(keyValue);
            }
            /// <summary>
            /// 根据表达式查询一个数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <returns>实体</returns>
            public virtual Sys_Role FindEntity(Expression<Func<Sys_Role, bool>> predicate)
            {
                return base.FindEntity(predicate);
            }
            /// <summary>
            /// 查询IQueryable列表
            /// </summary>
            /// <returns>IQueryable列表</returns>
            public virtual IQueryable<Sys_Role> IQueryable()
            {
                return base.IQueryable();
            }
            /// <summary>
            /// 根据表达式查询IQueryable列表数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <returns>IQueryable列表</returns>
            public virtual IQueryable<Sys_Role> IQueryable(Expression<Func<Sys_Role, bool>> predicate)
            {
                return base.IQueryable(predicate);
            }
            /// <summary>
            /// 根据Sql查询数据
            /// </summary>
            /// <param name="strSql">Sql</param>
            /// <returns>数据列表</returns>
            public virtual List<Sys_Role> FindList(string strSql)
            {
                return base.FindList(strSql);
            }
            /// <summary>
            /// 根据Sql查询数据
            /// </summary>
            /// <param name="strSql">Sql</param>
            /// <param name="dbParameter">参数列表</param>
            /// <returns>数据列表</returns>
            public virtual List<Sys_Role> FindList(string strSql, DbParameter[] dbParameter)
            {
                return base.FindList(strSql,dbParameter);
            }
            /// <summary>
            /// 查询分页数据
            /// </summary>
            /// <param name="pagination">分页参数</param>
            /// <returns>数据列表</returns>
            public virtual List<Sys_Role> FindList(Pagination pagination)
            {
                return base.FindList(pagination);
            }
            /// <summary>
            /// 查询表达式查询分页数据
            /// </summary>
            /// <param name="predicate">表达式</param>
            /// <param name="pagination">分页参数</param>
            /// <returns>数据列表</returns>
            public virtual List<Sys_Role> FindList(Expression<Func<Sys_Role, bool>> predicate, Pagination pagination)
            {
                return base.FindList(predicate,pagination);
            }
        }
    }
    View Code

    这样就完成了批量生成文件的功能了

    项目是DM.T4的项目结构

    ModelAuto.ttinclude

    <#@ assembly name="System.Core"#>
    <#@ assembly name="EnvDTE"#>
    <#@ import namespace="System.Collections.Generic"#>
    <#@ import namespace="System.IO"#>
    <#@ import namespace="System.Text"#>
    <#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
    
    <#+
    
    class Manager
    {
        public struct Block {
            public String Name;
            public int Start, Length;
        }
    
        public List<Block> blocks = new List<Block>();
        public Block currentBlock;
        public Block footerBlock = new Block();
        public Block headerBlock = new Block();
        public ITextTemplatingEngineHost host;
        public ManagementStrategy strategy;
        public StringBuilder template;
        public String OutputPath { get; set; }
    
        public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
            this.host = host;
            this.template = template;
            OutputPath = String.Empty;
            strategy = ManagementStrategy.Create(host);
        }
    
        public void StartBlock(String name) {
            currentBlock = new Block { Name = name, Start = template.Length };
        }
    
        public void StartFooter() {
            footerBlock.Start = template.Length;
        }
    
        public void EndFooter() {
            footerBlock.Length = template.Length - footerBlock.Start;
        }
    
        public void StartHeader() {
            headerBlock.Start = template.Length;
        }
    
        public void EndHeader() {
            headerBlock.Length = template.Length - headerBlock.Start;
        }    
    
        public void EndBlock() {
            currentBlock.Length = template.Length - currentBlock.Start;
            blocks.Add(currentBlock);
        }
    
        public void Process(bool split) {
            String header = template.ToString(headerBlock.Start, headerBlock.Length);
            String footer = template.ToString(footerBlock.Start, footerBlock.Length);
            blocks.Reverse();
            foreach(Block block in blocks) {
                String fileName = Path.Combine(OutputPath, block.Name);
                if (split) {
                    String content = header + template.ToString(block.Start, block.Length) + footer;
                    strategy.CreateFile(fileName, content);
                    template.Remove(block.Start, block.Length);
                } else {
                    strategy.DeleteFile(fileName);
                }
            }
        }
    }
    
    class ManagementStrategy
    {
        internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
            return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
        }
    
        internal ManagementStrategy(ITextTemplatingEngineHost host) { }
    
        internal virtual void CreateFile(String fileName, String content) {
            File.WriteAllText(fileName, content);
        }
    
        internal virtual void DeleteFile(String fileName) {
            if (File.Exists(fileName))
                File.Delete(fileName);
        }
    }
    
    class VSManagementStrategy : ManagementStrategy
    {
        private EnvDTE.ProjectItem templateProjectItem;
    
        internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
            IServiceProvider hostServiceProvider = (IServiceProvider)host;
            if (hostServiceProvider == null)
                throw new ArgumentNullException("Could not obtain hostServiceProvider");
    
            EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
            if (dte == null)
                throw new ArgumentNullException("Could not obtain DTE from host");
    
            templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
        }
    
        internal override void CreateFile(String fileName, String content) {
            base.CreateFile(fileName, content);
            ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
        }
    
        internal override void DeleteFile(String fileName) {
            ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
        }
    
        private void FindAndDeleteFile(String fileName) {
            foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
                if (projectItem.get_FileNames(0) == fileName) {
                    projectItem.Delete();
                    return;
                }
            }
        }
    }#>
    View Code

    ModelManager.cs

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace DM.T4
    {
        public class ModelManager
        {
            /// <summary>
            /// 数据库连接字符串
            /// </summary>
            private const string CONNECTION_STRING = "Server=.;Initial Catalog=DocumentManage;User ID=sa;Password=123456";
            /// <summary>
            /// 用户信息表名
            /// </summary>
            private const string PERSONINFO_TABLE_NAME = "USERINFO";
            /// <summary>
            /// 根据表名查询表结构信息
            /// </summary>
            private const string SELECT_SCHEMA_BY_TABLE_NAME = @"select d.name as 表名       --如果表名相同就返回空  
         , ddd.value as 表说明      --如果表名相同就返回空  
         , a.colorder                                       as 字段序号
         , a.name                                           as 字段名
         , (case
                when columnproperty(a.id, a.name, 'IsIdentity') = 1 then
                    1
                else
                    0
            end
           )                                                as 是否自增标识
         , (case
                when
                (
                    select count(*)
                    from sys.sysobjects --查询主键  
                    where (name in
                           (
                               select name
                               from sys.sysindexes
                               where (id = a.id)
                                     and (indid in
                                          (
                                              select indid
                                              from sys.sysindexkeys
                                              where (id = a.id)
                                                    and (colid in
                                                         (
                                                             select colid from sys.syscolumns where (id = a.id) and (name = a.name)
                                                         )
                                                        )
                                          )
                                         )
                           )
                          )
                          and (xtype = 'PK')
                ) > 0 then
                    1
                else
                   0
            end
           )                                                as 主键       --查询主键END  
         , b.name                                           as 数据类型
         , a.length                                         as 占用字节数
         , columnproperty(a.id, a.name, 'PRECISION')        as 长度
         , isnull(columnproperty(a.id, a.name, 'Scale'), 0) as 小数位
         , (case
                when a.isnullable = 1 then
                    1
                else
                    0
            end
           )                                                as 允许空
         , isnull(e.text, '')                               as 缺省值
         , isnull(g.value, '')                              as 备注
    from sys.syscolumns                   a
        left join sys.systypes            b
            on a.xtype = b.xusertype
        inner join sys.sysobjects         d
            on a.id = d.id
               and d.xtype = 'U'
               and d.name <> 'dtproperties'
        left outer join
        (
            select major_id
                 , value
            from sys.extended_properties
            where name = 'MS_Description'
                  and minor_id = 0
        )                                 as ddd
            on a.id = ddd.major_id
        left join sys.syscomments         e
            on a.cdefault = e.id
        left join sys.extended_properties g
            on a.id = g.major_id
               and a.colid = g.minor_id
    where d.name='{0}'
    order by a.id
           , a.colorder;";
    
            private const string TABLE_FK_SQL = @"select
    a.name as 约束名,
    object_name(b.parent_object_id) as 外键表,
    c.name as 外键列,
    object_name(b.referenced_object_id) as 主健表,
    d.name as 主键列
    from sys.foreign_keys A
    inner join sys.foreign_key_columns B on A.object_id=b.constraint_object_id
    inner join sys.columns C on B.parent_object_id=C.object_id and B.parent_column_id=C.column_id 
    inner join sys.columns D on B.referenced_object_id=d.object_id and B.referenced_column_id=D.column_id 
    where  object_name(b.parent_object_id)!=object_name(b.referenced_object_id)";
    
            /// <summary>
            /// 获得数据连接
            /// </summary>
            /// <returns></returns>
            private SqlConnection GetConnection()
            {
                return new SqlConnection(SqlHelper.sqlConnectionStr);
            }
    
            /// <summary>
            /// 得到当前用户的所有表名
            /// </summary>
            /// <returns></returns>
            public List<string> GetTableList()
            {
                string sql = "select table_name from information_schema.tables";
                DataTable dt = SqlHelper.ExecuteDataTable(sql);
                List<string> list = new List<string>();
                if (dt != null && dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        list.Add(dt.Rows[i][0].ToString());
                    }
                }
                return list;
            }
    
            /// <summary>
            /// 得到所有表主外键关系
            /// </summary>
            /// <returns></returns>
            public List<FK> GetFK()
            {
                DataTable dt = SqlHelper.ExecuteDataTable(TABLE_FK_SQL);
                List<FK> lst = new List<FK>();
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    FK fk = new FK()
                    {
                        FKName = dt.Rows[i]["约束名"].ToString(),
                        WJ_Table = dt.Rows[i]["外键表"].ToString(),
                        WJ_Field = dt.Rows[i]["外键列"].ToString(),
                        ZJ_Table = dt.Rows[i]["主健表"].ToString(),
                        ZJ_Field = dt.Rows[i]["主键列"].ToString()
                    };
                    lst.Add(fk);
                }
    
                return lst;
            }
            /// <summary>
            /// 释放连接
            /// </summary>
            /// <param name="con"></param>
            private void ReleaseConnection(SqlConnection con)
            {
                if (con != null)
                {
                    if (con.State == ConnectionState.Open)
                    {
                        con.Close();
                    }
                }
            }
    
            public DataTable GetTableSchema(string tableName)
            {
                DataTable dt = SqlHelper.ExecuteDataTable(string.Format(SELECT_SCHEMA_BY_TABLE_NAME, tableName));
                return dt;
            }
    
            /// <summary>
            /// SQL[不完善,需要的自己改造]
            /// </summary>
            /// <param name="type"></param>
            /// <returns></returns>
            public string TransFromSqlType(string type)
            {
                type = type.ToLower();
    
                switch (type)
                {
                    case "int": return "int";
                    case "bigint": return "Int64";
                    case "smallint": return "Int16";
                    case "text":
                    case "char":
                    case "nchar":
                    case "ntext":
                    case "nvarchar":
                    case "varchar": return "string";
                    case "varbinary":
                    case "image":
                    case "binary": return "Byte[]";
                    case "tinyint": return "byte";
                    case "bit": return "bool";
                    case "date":
                    case "time":
                    case "smalldatetime":
                    case "timestamp":
                    case "datetime": return "DateTime";
                    case "money":
                    case "numeric":
                    case "smallmoney":
                    case "decimal": return "decimal";
                    case "float": return "double";
                    case "real": return "Single";
                    default: return "string";
                }
            }
        }
        public class FK
        {
            public string FKName { get; set; }
            public string WJ_Table { get; set; }
            public string WJ_Field { get; set; }
            public string ZJ_Table { get; set; }
            public string ZJ_Field { get; set; }
        }
    }
    View Code

    SqlHelper.cs

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace DM.T4
    {
        public class SqlHelper
        {
            public static string sqlConnectionStr = "Server=.;Initial Catalog=DocumentManage;User ID=sa;Password=123456";
            public static DataTable ExecuteDataTable(string sql, params SqlParameter[] paramList)
            {
                using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
                {
                    conn.Open();
                    using (SqlCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        DataTable dt = new DataTable();
                        SqlDataAdapter adapter = new SqlDataAdapter(command);
                        adapter.Fill(dt);
                        return dt;
                    }
                }
            }
    
            public static int ExecuteNonQuery(string sql, params SqlParameter[] paramList)
            {
                using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
                {
                    conn.Open();
                    using (SqlCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteNonQuery();
                    }
                }
            }
    
            public static object ExecuteScalar(string sql, params SqlParameter[] paramList)
            {
                using (SqlConnection conn = new SqlConnection(sqlConnectionStr))
                {
                    conn.Open();
                    using (SqlCommand command = conn.CreateCommand())
                    {
                        command.CommandText = sql;
                        command.Parameters.AddRange(paramList);
                        return command.ExecuteScalar();
                    }
                }
            }
        }
    
    }
    View Code
  • 相关阅读:
    pg 基础操作
    mybatis+pg常见错误
    mybatis 需要注意事项
    java编程中的Dao,service,controller,View
    java 中的spring基础
    werkzeug(flask)中的local,localstack,localproxy探究
    gevent
    cookie和session
    关于redis数据库的简单思考
    对阻塞,非阻塞,同步,异步的深入理解
  • 原文地址:https://www.cnblogs.com/bfyx/p/9918016.html
Copyright © 2011-2022 走看看