轻量级ORM 利用T4模板 批量生成多文件 实体和业务逻辑 代码

Posted 仰望星空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了轻量级ORM 利用T4模板 批量生成多文件 实体和业务逻辑 代码相关的知识,希望对你有一定的参考价值。

FluentData,它是一个轻量级框架,关注性能和易用性。 

下载地址:FlunenData.Model

利用T4模板,【MultipleOutputHelper.ttinclude】批量生成多文件

基本语法:

1. 初始化:获取MultipleOutputHelper.ttinclude文件模板 在T4模板导入

  //导入MultipleOutputHelper.ttinclude文件 路径
      <#@include file="$(SolutionDir)\\ORM.Model\\T4\\MultipleOutputHelper.ttinclude"#> 
  //初始化Manager对象 
      var manager = Manager.Create(Host, GenerationEnvironment);  

2.文件块:使用代码标识区分生成的代码块的范围
          manager.StartNewFile(tb_name+".cs");
         //代码块
         manager.EndBlock();

3.编译执行:使用Process方法,进行文件分割

 manager.Process(true);  
 

实践:

t4-fluntdata

1.批量生成实体类

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Data" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>

//  导入MultipleOutputHelper.ttinclude文件
<#@include file="$(SolutionDir)\\My.Model\\T4\\MultipleOutputHelper.ttinclude"#> 

<#        
        string connectionString= "server=qq;database=db;uid=sa;pwd=sa;";        
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
    
        string selectQuery ="SET FMTONLY ON; select * from @tableName; SET FMTONLY OFF;";
        SqlCommand command = new SqlCommand(selectQuery,conn);
        SqlDataAdapter ad = new SqlDataAdapter(command);
        System.Data.DataSet ds = new DataSet(); 
  
        var manager = Manager.Create(Host, GenerationEnvironment);  

        System.Data.DataTable schema = conn.GetSchema("Tables");
        foreach(System.Data.DataRow row in schema.Rows)
        {    
            ds.Tables.Clear();
            string tb_name= row["TABLE_NAME"].ToString();        
            command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString());
            ad.FillSchema(ds, SchemaType.Mapped,tb_name);  
            manager.StartNewFile(tb_name+".cs");#>

using FluentData;
using System;
using System.Collections.Generic;
namespace My.Model
{    
    /// <summary>
    /// 实体-<#=tb_name#> 
    /// </summary>
    public partial class <#=tb_name#>    
    {    
        <#
        PushIndent("          ");
        foreach (DataColumn dc in ds.Tables[0].Columns) 
        {
            WriteLine("public " + dc.DataType.Name+ (dc.AllowDBNull && dc.DataType.Name.ToLower() != "string" ? "? ": " ") + dc.ColumnName + " { get; set; }");
        }
        PopIndent();
        #>
    }
}
    
<#
        manager.EndBlock();    
         }            
        conn.Close();  
       manager.Process(true);  
        #> 

 

2.批量生成基础业务逻辑

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="System.Data" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>

//  导入MultipleOutputHelper.ttinclude文件
<#@include file="$(SolutionDir)\\MY.Model\\T4\\MultipleOutputHelper.ttinclude"#> 

<#        
        string connectionString= "server=QQ;database=DB;uid=sa;pwd=sa;";        
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
    
        string selectQuery ="SET FMTONLY ON; select * from @tableName; SET FMTONLY OFF;";
        SqlCommand command = new SqlCommand(selectQuery,conn);
        SqlDataAdapter ad = new SqlDataAdapter(command);
        System.Data.DataSet ds = new DataSet(); 
  
        var manager = Manager.Create(Host, GenerationEnvironment);  

        System.Data.DataTable schema = conn.GetSchema("Tables");
        foreach(System.Data.DataRow row in schema.Rows)
        {    
            ds.Tables.Clear();
            string tb_name= row["TABLE_NAME"].ToString();        
            command.CommandText = selectQuery.Replace("@tableName",row["TABLE_NAME"].ToString());
            ad.FillSchema(ds, SchemaType.Mapped,tb_name);  
            manager.StartNewFile(tb_name+"Action.cs");#>


using System;
using System.Collections.Generic;
using MY.Model;
using FluentData;
namespace MY.BLL
{    
    
    /// <summary>
    /// <#=tb_name#> 操作类
    /// </summary>
    public partial class <#=tb_name#>Action
    {<#
        string fkQuery = " SELECT f.name AS ForeignKey,";
        fkQuery += " OBJECT_NAME(f.parent_object_id) AS TableName, ";
        fkQuery += " COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName, ";
        fkQuery += " OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, ";
        fkQuery += " COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName ";
        fkQuery += " FROM ";
        fkQuery += " sys.foreign_keys AS f ";
        fkQuery += " INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id ";
        fkQuery += " where OBJECT_NAME(f.parent_object_id) = \'" +tb_name +"\'";

        List<string> fkColumnNames = new List<string>();
        Dictionary<string, string> parentTables = new Dictionary<string, string>();
    
        SqlCommand command2 = new SqlCommand(fkQuery,conn);
        using(var dr = command2.ExecuteReader())
        {
            while(dr.Read())
            {
                fkColumnNames.Add(dr["ColumnName"].ToString());
                parentTables.Add(dr["ColumnName"].ToString(), dr["ReferenceTableName"].ToString());
            }
            dr.Close();
        }
    
        
    

        List<DataColumn> fkColumns = new List<DataColumn>();
        foreach(string fkColumnName in fkColumnNames)
        {
            foreach (DataColumn dc in ds.Tables[0].Columns) 
            {
                if(dc.ColumnName == fkColumnName)
                    fkColumns.Add(dc);
            }
        }

        List<string> primaryKeyParamsWithTypes = new List<string>();
        List<string> primaryKeyParams = new List<string>();
        List<string> whereItems = new List<string>();
        List<string> automapItems = new List<string>();
        foreach(DataColumn pk in ds.Tables[0].PrimaryKey)
        {
            primaryKeyParamsWithTypes.Add(string.Format("{0} {1}", pk.DataType.Name, this.ToCamelCase(pk.ColumnName)));
            primaryKeyParams.Add(pk.ColumnName);
            whereItems.Add(string.Format("{0} = @{1}", pk.ColumnName, pk.ColumnName.ToLower()));
            automapItems.Add(string.Format("x.{0}", pk.ColumnName));
        }

        string updateAutomap = string.Empty;
    if(automapItems.Count > 0){
        if(automapItems.Count > 1)
            updateAutomap = "new { " + string.Join(", ", automapItems.ToArray()) + " }";
        else
            updateAutomap = automapItems[0];
            }
        #>

        

        public static <#=tb_name#> Select(<#=string.Join(", ", primaryKeyParamsWithTypes.ToArray())#>)
        {
            using(var context = db.Context())
            {
                return context.Sql(" SELECT * FROM <#=tb_name#> WHERE <#=string.Join(" AND ", whereItems.ToArray())#> ")
                    <#foreach(string pkp in primaryKeyParams) 
                    {
                        WriteLine(".Parameter(\\"" + pkp.ToLower() + "\\", " + this.ToCamelCase(pkp) + ")");
                    }
                    #>
                    .QuerySingle<<#=tb_name#>>();
            }
        }

        public static List<<#=tb_name#>> SelectAll()
        {
            return SelectAll(string.Empty);
        }

        public static List<<#=tb_name#>> SelectAll(string sortExpression)
        {
            return SelectAll(0, 0, sortExpression);
        }

        public static List<<#=tb_name#>> SelectAll(int startRowIndex, int maximumRows, string sortExpression)
        {
            using (var context = db.Context())
            {
                var select = context.Select<<#=tb_name#>>(" * ")
                    .From(" <#=tb_name#> ");

                if (maximumRows > 0)
                {
                    if (startRowIndex == 0) 
                        startRowIndex = 1;

                    select.Paging(startRowIndex, maximumRows);
                }

                if (!string.IsNullOrEmpty(sortExpression))
                    select.OrderBy(sortExpression);

                return select.QueryMany();
            }
        }

        public static int CountAll()
        {
            using (var context = db.Context())
            {
                return context.Sql(" SELECT COUNT(*) FROM <#=tb_name#> ")
                    .QuerySingle<int>();
            }
        }

        <#
        foreach(DataColumn dc in fkColumns)
        {
        #>

        public static List<<#=tb_name#>> SelectBy<#=parentTables[dc.ColumnName]#>(<#=dc.DataType.Name#> <#=this.ToCamelCase(dc.ColumnName)#>)
        {
            return SelectBy<#=parentTables[dc.ColumnName]#>(<#=this.ToCamelCase(dc.ColumnName)#>, string.Empty);
        }

        public static List<<#=tb_name#>> SelectBy<#=parentTables[dc.ColumnName]#>(<#=dc.DataType.Name#> <#=this.ToCamelCase(dc.ColumnName)#>, string sortExpression)
        {
            return SelectBy<#=parentTables[dc.ColumnName]#>(<#=this.ToCamelCase(dc.ColumnName)#>, 0, 0, sortExpression);
        }

        public static List<<#=tb_name#>> SelectBy<#=parentTables[dc.ColumnName]#>(<#=dc.DataType.Name#> <#=this.ToCamelCase(dc.ColumnName)#>, int startRowIndex, int maximumRows, string sortExpression)
        {
            using (var context = db.Context())
            {
                var select = context.Select<<#=tb_name#>>(" * ")
                    .From(" <#=tb_name#> ")
                    .Where(" <#=dc.ColumnName#> = @<#=dc.ColumnName.ToLower()#> ")
                    .Parameter("<#=dc.ColumnName.ToLower()#>", <#=this.ToCamelCase(dc.ColumnName)#>);

                if (maximumRows > 0)
                {
                    if (startRowIndex == 0) 
                        startRowIndex = 1;

                    select.Paging(startRowIndex, maximumRows);
                }

                if (!string.IsNullOrEmpty(sortExpression))
                    select.OrderBy(sortExpression);

                return select.QueryMany();
            }
        }

        public static int CountBy<#=parentTables[dc.ColumnName]#>(<#=dc.DataType.Name#> <#=this.ToCamelCase(dc.ColumnName)#>)
        {
            using (var context = db.Context())
            {
                return context.Sql(" SELECT COUNT(*) FROM <#=tb_name#> WHERE <#=dc.ColumnName#> = @<#=dc.ColumnName.ToLower()#>")
                    .Parameter("<#=dc.ColumnName.ToLower()#>", <#=this.ToCamelCase(dc.ColumnName)#>)
                    .QuerySingle<int>();
            }
        }
        <#}#>

<#if(ds.Tables[0].PrimaryKey != null && ds.Tables[0].PrimaryKey.Length == 1 && ds.Tables[0].PrimaryKey[0].AutoIncrement) {#>
        public static bool Insert(<#=tb_name#> <#=this.ToCamelCase(tb_name)#>) 
        {
            using (var context = db.Context())
            {
                int id = context.Insert<<#=tb_name#>>("<#=tb_name#>", <#=this.ToCamelCase(tb_name)#>)
                    .AutoMap(x => x.<#=primaryKeyParams[0]#>)
                    .ExecuteReturnLastId<int>();

                <#=this.ToCamelCase(tb_name)#>.<#=primaryKeyParams[0]#> = id;
                return id > 0;
            }
        }
<#
}
else
{
#>
        public static bool Insert(<#=tb_name#> <#=this.ToCamelCase(tb_name)#>) 
        {
            using (var context =db.Context())
            {
                return context.Insert<<#=tb_name#>>("<#=tb_name#>", <#=this.ToCamelCase(tb_name)#>)
                    .Execute() > 0;
            }
        }
<#}#>
        public static bool Update(<#=tb_name#> <#=this.ToCamelCase(tb_name)#>)
        {
            using (var context = db.Context())
            {
                return context.Update<<#=tb_name#>>("<#=tb_name#>", <#=this.ToCamelCase(tb_name)#>)
                    .AutoMap(x => <#=updateAutomap#>)
                    <#foreach(string pkp in primaryKeyParams){#>
                    .Where("<#=pkp#>", <#=this.ToCamelCase(tb_name)#>.<#=pkp#>)
                    <#}#>
                    .Execute() > 0;
            }
        }

        public static bool Delete(<#=tb_name#> <#=this.ToCamelCase(tb_name)#>) 
        {
            return Delete(<#=string.Join(", ", primaryKeyParams.Select(x=> this.ToCamelCase(tb_name) + "." + x).ToArray())#>);
        }

        public static bool Delete(<#=string.Join(", ", primaryKeyParamsWithTypes.ToArray())#>)
        {
            using (var context = db.Context())
            {
                return context.Sql(" DELETE FROM Product WHERE <#=string.Join(" AND ", whereItems.ToArray())#> ")
                    <#foreach(string pkp in primaryKeyParams) {
                        WriteLine(".Parameter(\\"" + pkp.ToLower() + "\\", " + this.ToCamelCase(pkp) + ")");
                    }#>
                    .Execute() > 0;
            }
        }
    }
    
}
    
<#
        manager.EndBlock();    
         }            
        conn.Close();  
       manager.Process(true);  
        #> 



<#+
    public string ToCamelCase(string value)
    {
        if(string.IsNullOrEmpty(value)) 
            return string.Empty;
        
        string firstLetter = value.Substring(0, 1);
        string rest = value.Substring(1, value.Length - 1);
        return firstLetter.ToLower() + rest;
    }
#>

CTRL+S  自动生成

 下载地址:FlunenData.Model

以上是关于轻量级ORM 利用T4模板 批量生成多文件 实体和业务逻辑 代码的主要内容,如果未能解决你的问题,请参考以下文章

poi根据模版生成多页word,并压缩下载

T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll

20170727xlVBA根据总名单和模板生成多页名单

为什么使用T4修改EF中的实体?

实体框架数据库首先生成多对多中间表,其中没有额外的列

Visual Studio Package 插件开发之自动生成实体工具