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

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介:

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

 

完成!即可快速开发了!



    本文转自曾祥展博客园博客,原文链接:http://www.cnblogs.com/zengxiangzhan/p/3250105.html ,如需转载请自行联系原作者



相关文章
|
5月前
|
数据库连接 数据库
实现加载驱动、得到数据库对象、关闭资源的代码复用,将代码提取到相应的工具包里边。优化程序
该博客文章展示了如何通过创建工具类`Connectiontools`实现数据库连接、语句执行以及资源关闭的代码复用,以优化程序并提高数据库操作的效率和安全性。
|
5月前
|
存储 开发框架 前端开发
EAV模型(实体-属性-值)的设计和低代码的处理方案(2)--数据的查询处理
EAV模型(实体-属性-值)的设计和低代码的处理方案(2)--数据的查询处理
|
5月前
|
存储 开发框架 前端开发
EAV模型(实体-属性-值)的设计和低代码的处理方案(3)-- 实体属性定义及前端列表展示和数据录入处理
EAV模型(实体-属性-值)的设计和低代码的处理方案(3)-- 实体属性定义及前端列表展示和数据录入处理
|
8月前
|
JavaScript 前端开发 测试技术
编写JavaScript模块化代码主要涉及将代码分割成不同的文件或模块,每个模块负责处理特定的功能或任务
【5月更文挑战第10天】编写JavaScript模块化代码最佳实践:使用ES6模块或CommonJS(Node.js),组织逻辑相关模块,避免全局变量,封装细节。利用命名空间和目录结构,借助Webpack处理浏览器环境的模块。编写文档和注释,编写单元测试以确保代码质量。通过这些方法提升代码的可读性和可维护性。
67 3
|
7月前
|
XML 搜索推荐 数据格式
资源描述框架的用途及实际应用解析
**RDF(资源描述框架)**是一种用于机器理解网络资源的框架,使用XML编写。它通过URI标识资源,用属性描述资源,便于计算机应用程序处理信息。RDF在语义网上促进信息的确切含义和自动处理,使得网络信息可被整合。RDF语句由资源、属性和属性值组成。RDF文档包括`&lt;rdf:RDF&gt;`根元素和`&lt;rdf:Description&gt;`元素,后者用`about`属性标识资源。RDF还支持容器(如`&lt;Bag&gt;`、`&lt;Seq&gt;`和`&lt;Alt&gt;`)来描述集合。RDFS是RDF的扩展,提供描述类和属性的框架,而达布林核心是一组预定义属性,用于描述文
207 0
|
8月前
【突破常规:让函数规范成为注目的亮点】(上)
【突破常规:让函数规范成为注目的亮点】
|
8月前
【突破常规:让函数规范成为注目的亮点】(下)
【突破常规:让函数规范成为注目的亮点】
|
存储 测试技术 数据安全/隐私保护
RobotFrameWork接口项目分层及通用控制方式
RobotFrameWork接口项目分层及通用控制方式
1013 0
RobotFrameWork接口项目分层及通用控制方式
|
算法 数据库
【自然框架】元数据的数据库结构的详细说明和示例(一):项目描述部分
自然框架在线演示:  http://pthuanyu.com/   【自然框架】PowerDesigner 格式的元数据的表结构   自然框架的源码、Demo、数据库、说明文档的下载,还是老地方:自然框架的源代码、Demo、数据库、配置信息管理程序下载(2010.
964 0
|
数据库
【自然框架】之通用权限:数据库设计的几种使用方式
      上次《【自然框架】之通用权限:用PowerDesigner重新设计了一下数据库,有ER图和表关系图 》里说了一大堆的表,好多人说太复杂了,做到权限到模块就可以了。       这个嘛,我也没有说所有的表都要一起使用呀。
1213 0