C#实现代码生成器
最近在用layui做后台管理,增删改查这些一成不变的东西写起来浪费大量时间,于是做了个简单的代码生成器快速生成
代码生成器的原理其实很简单,都是基于模板实现替换,Razor是个不错的选择(或者Nvelocity。。),还可以用字符串占位符替换的方式生成。
1. 技术栈
0.Asp.net
1.模板引擎RazorEngine
2.ORM使用SqlSugar
3.生成压缩包SharpZipLib
2.源码下载
https://gitee.com/huzhihao/code_generator.git
3.代码分析
核心代码就两个cs:
Coder.cs
------------------------------------------
using MySqlSugar;
using RazorEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text; namespace ConsoleApp1
{
public class Coder
{
private SqlSugarClient _sqlsugarClient;
public SqlSugarClient db
{
get
{
if (_sqlsugarClient == null)
{
var conn = "Database=easycms;Data Source=127.0.0.1;User Id=root;Password=root;pooling=false;CharSet=utf8;port=3306;SslMode=None";
var db = new SqlSugarClient(conn);
_sqlsugarClient = db;
}
return _sqlsugarClient;
}
} public string entity_template { get; set; }
public string dto_template { get; set; }
public string app_template { get; set; }
public string ctrl_template { get; set; } /// <summary>
/// 数据库名
/// </summary>
public string dbschema { get; set; }
public Coder()
{
var path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "实体类razor.txt");
entity_template = File.ReadAllText(path); var dto_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "DTO类Razor.txt");
dto_template = File.ReadAllText(dto_path); var app_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "应用类razor.txt");
app_template = File.ReadAllText(app_path); var ctrl_path = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Template", "控制器razor.txt");
ctrl_template = File.ReadAllText(ctrl_path); dbschema = "easycms";
} public string Builder()
{
var keyword = "sys_user,sys_dict,sys_parameter,sys_role"; var dir = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate");
if (Directory.Exists(dir))
{
Directory.Delete(dir, true);
} StringBuilder builder = new StringBuilder();
var tables = db.SqlQuery<TableInfo>(string.Format(@"select table_name,table_comment from information_schema.tables
where table_schema='{0}'", dbschema)).ToList();
foreach (var tb in keyword.Split(','))
{
var tablecomment = tables.Find(c => c.table_name == tb).table_comment;
var ret = RazorParse(tb, tablecomment);
builder.Append(ret);
} var srcdir = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate", "Code");
var folders = new List<string>();
folders.Add(srcdir);
var bl = new ZipHelper().ZipManyFilesOrDictorys(folders.AsEnumerable(),
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate", "Code.zip"), ""); return builder.ToString(); ;
} public string RazorParse(string tablename, string tablecomment)
{
StringBuilder builder = new StringBuilder();
var columsInfo = db.SqlQuery<ColumnInfo>(string.Format(@"select table_name,column_name,ordinal_position,is_nullable,data_type,character_maximum_length,column_key,column_comment
from information_schema.COLUMNS
where table_schema = '{0}' and table_name = '{1}'", dbschema, tablename)).ToList(); foreach (var item in columsInfo)
{
item.data_type = Utils.GetCsType(item.data_type);
if (!item.data_type.Equals("string") && item.is_nullable.Equals("YES"))
{
item.data_type = item.data_type + "?";
}
} #region entity
var entity_result = Razor.Parse(entity_template, new
{
EntityNameSpace = "Ace.Entity.CMS",
EntityName = tablename,
Columns = columsInfo
},"entity"); Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Entity", $"{tablename}.cs")
, entity_result);
builder.Append(entity_result);
#endregion #region dto
var dto_result = Razor.Parse(dto_template, new
{
DtoNameSpace = "Ace.Application.CMS.Models",
DtoName = Utils.ToCamelName(tablename) + "Info",
Columns = columsInfo
},"dto");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Dto", $"{Utils.ToCamelName(tablename) + "Info"}.cs")
, dto_result);
builder.Append(dto_result);
#endregion #region app
var app_result = Razor.Parse(app_template, new
{
AppNameSpace = "Ace.Application.CMS.Implements",
DtoName = Utils.ToCamelName(tablename) + "Info",
AppClassName = Utils.ToCamelName(tablename),
Table = tablename,
Columns = columsInfo
},"app");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Application", $"{Utils.ToCamelName(tablename) + "Service"}.cs")
, app_result);
builder.Append(app_result);
#endregion #region controller
var ctrl_result = Razor.Parse(ctrl_template, new
{
AppClassName = Utils.ToCamelName(tablename),
DtoName = Utils.ToCamelName(tablename) + "Info",
TableComment = tablecomment,
},"ctrl");
Utils.Save(
Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "CodeGenerate\\Code\\Controller", $"{Utils.ToCamelName(tablename) + "Controller"}.cs")
, ctrl_result);
builder.Append(ctrl_result);
#endregion return builder.ToString();
} public class ColumnInfo
{
public string table_name { get; set; }
public string column_name { get; set; }
public int? ordinal_position { get; set; }
public string is_nullable { get; set; }
public string data_type { get; set; }
public int? character_maximum_length { get; set; }
public string column_key { get; set; }
public string column_comment { get; set; }
} public class TableInfo
{
public string table_name { get; set; }
public string table_comment { get; set; } } }
}
-----------------------------------
Util.cs
-----------------------------------
using System.IO;
using System.Text; namespace ConsoleApp1
{
public class Utils
{ /// <summary>
/// 类型转化
/// </summary>
/// <param name="dbType"></param>
/// <returns></returns>
public static string GetCsType(string dbType)
{
string csType = "";
switch (dbType.ToLower())
{
case "varchar":
case "varchar2":
case "nvarchar":
case "nvarchar2":
case "char":
case "nchar":
case "text":
case "longtext":
case "string":
csType = "string";
break; case "date":
case "datetime":
case "smalldatetime":
case "timestamp":
csType = "DateTime";
break; case "int":
case "number":
case "smallint": case "integer":
csType = "int";
break; case "bigint":
csType = "Int64";
break; case "float":
case "numeric":
case "decimal":
case "money":
case "smallmoney":
case "real":
case "double":
csType = "decimal";
break;
case "tinyint":
case "bit":
csType = "bool";
break; case "binary":
case "varbinary":
case "image":
case "raw":
case "long":
case "long raw":
case "blob":
case "bfile":
csType = "byte[]";
break; case "uniqueidentifier":
csType = "Guid";
break; case "xml":
case "json":
csType = "string";
break;
default:
csType = "object";
break;
} return csType;
} /// <summary>
/// 保存
/// </summary>
/// <param name="path"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string Save(string path, string content)
{
string dir = path.Substring(0, path.LastIndexOf("\\") + 1);
if (!System.IO.Directory.Exists(dir)) System.IO.Directory.CreateDirectory(dir);
File.WriteAllText(path, content);
return path;
} private static System.Text.RegularExpressions.Regex regSpace = new System.Text.RegularExpressions.Regex(@"\s"); /// <summary>
/// 去掉空格
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ReplaceSpace(string value)
{
if (string.IsNullOrEmpty(value))
return string.Empty;
char firstChar = value[0];
if (firstChar >= 48 && firstChar <= 57)
{
value = "_" + value;
}
return regSpace.Replace(value.Trim(), " ");
} /// <summary>
/// 首字母大写
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToUpperFirstword(string value)
{
if (string.IsNullOrEmpty(value))
return string.Empty; return value.Substring(0, 1).ToUpper() + value.Substring(1); } /**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
* 例如:HELLO_WORLD->HelloWorld
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
/// <summary>
/// 转换为驼峰命名
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string ToCamelName(string name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || string.IsNullOrEmpty(name))
{
// 没必要转换
return "";
}
else if (!name.Contains("_"))
{
// 不含下划线,仅将首字母大写
return name.Substring(0, 1).ToUpper() + name.Substring(1).ToLower();
}
// 用下划线将原始字符串分割
string[] camels = name.Split('_');
foreach (string camel in camels)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (string.IsNullOrEmpty(camel))
{
continue;
}
// 处理真正的驼峰片段
//if (result.Length == 0)
//{
// // 第一个驼峰片段,全部字母都小写
// result.Append(camel.ToLower());
//}
//else
//{
// 其他的驼峰片段,首字母大写
result.Append(camel.Substring(0, 1).ToUpper());
result.Append(camel.Substring(1).ToLower());
//}
}
return result.ToString();
}
}
}
C#实现代码生成器的更多相关文章
- springmvc SSM shiro redis 后台框架 多数据源 代码生成器
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单 下载地址 ; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类 ...
- 分享一个与ABP配套使用的代码生成器源码
点这里进入ABP系列文章总目录 分享一个与ABP配套使用的代码生成器源码 真对不起关注我博客的朋友, 因最近工作很忙, 很久没有更新博客了.以前答应把自用的代码生成器源码共享出来, 也一直没有时间整理 ...
- ABP配套代码生成器(ABP Code Generator)帮助文档,实现快速开发
ABP代码生成器介绍 针对abp这个框架做了一个代码生成器,功能强大.分为两大功能点,一个是数据层,一个是视图层. 数据服务层:通过它,可以实现表设计.领域层初始化.多语言.automapper自动注 ...
- 基于AgileEAS.NET SOA 中间件领域模型数据器快速打造自己的代码生成器
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- Razor Engine,实现代码生成器的又一件利器
Razor Engine,之前仅仅是ASP.NET MVC的一种View引擎,目前已经完全成为一种可以独立使用的模版引擎,并且已经成为了CodePlex上一个开源的项目(http://razoreng ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 更优美的Oracle数据库上的代码生成器
代码生成器进行了改进,针对Oracle数据库生成更优美的代码.这样生成出来的代码,更像微软的风格,更像C#.NET的标准规范,阅读起来也更优美.把Oracle表字段名默认大写, 有_分割等进行了优化, ...
- [NHibernate]代码生成器的使用
目录 写在前面 文档与系列文章 代码生成器的使用 总结 写在前面 前面的文章介绍了nhibernate的相关知识,都是自己手敲的代码,有时候显得特别的麻烦,比如你必须编写持久化类,映射文件等等,举得例 ...
- RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-29(提供下载)
本次主要更新内容: 1.增加对Oracle表创建语句的查看. 2.新增对MySql的代码生成支持. 3.全面重构对多线程的支持,改变以前会无故退出的现象. RDIFramework.NET代码生成器V ...
- RDIFramework.NET平台代码生成器V3.0版本全新发布-更新于20160518(提供下载)
最新版本请转到:RDIFramework.NET平台代码生成器V3.1版本全新发布-更新于2016-10-08(提供下载) RDIFramework.NET代码生成器V3.0版本修改了针对3.0版本的 ...
- XML代码生成器——XMLFACTORY 简介(四)
XML代码生成器——XMLFACTORY 简介(四) 这一篇我们讲“类属性”页签的配置功能,您将了解到:如何为元素子值指定类属性的名称,数据类型,及容器类型. 如果,你没看过这个系列的第一篇文章,请先 ...
随机推荐
- spark调优篇-oom 优化(汇总)
spark 之所以需要调优,一是代码执行效率低,二是经常 OOM 内存溢出 内存溢出无非两点: 1. Driver 内存不够 2. Executor 内存不够 Driver 内存不够无非两点: 1. ...
- 第11章:使用Python打造MySQL专家系统
1.Python语言高级特性 1).深入浅出Python生成器 1).生成器函数:与普通函数定义类似,使用yield语句而不是return语句返回结果.yield语句一次返回一个结果,在每个结果中间挂 ...
- k8s-prometheus 数据采集(node redis kubelet等)
apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: kube-ops data: prometheu ...
- 牛客 197E 01串
大意: 给定01串, 单点修改, 询问给定区间$[l,r]$, 假设$[l,r]$从左往右得到的二进制数为$x$, 每次操作增加或减少2的幂, 求最少操作数使得$x$为0. 线段树维护2*2矩阵表示低 ...
- centos7 + postgresql10
mysql被黑惨了,换了个超复杂的密码都不行,黑客会删除你所有的自定义库,然后插一个warning表,让你给他汇比特币. 提醒大家放在在公网的DB,要非常注意数据的安全性,万一被勒索了,真是mmp了. ...
- Dubbo 配置参数
关闭启动检查 在dubbo多模块项目启动的时候为了并行启动多个服务,缩短启动时间,需要解除模块之间的依赖检测 dubbo.consumer.check=false @Reference(check = ...
- java web开发跨域问题
分布式环境,前后端分离背景下跨域问题 1.1 设置页面document.domain去把2个页面之间的跨域交互统一 一级域名相同的情况下 调用者和页面提供者进行一个协调 页面提供者要在document ...
- celery最佳体验
目录 目录 不使用数据库作为 Broker 不要过分关注任务结果 实现优先级任务 应用 Worker 并发池的动态扩展 应用任务预取数 保持任务的幂等性 应用任务超时限制 善用任务工作流 合理应用 a ...
- SSH配置(同一服务器不同用户)
一.cxwh用户ssh免密登陆至xtjk用户 1.cxwh用户执行 ssh-keygen -t rsa -N "" -f /home/cxwh/.ssh/id_rsa cp /ho ...
- Mac上使用sunlogin向日葵软件远程控制电脑
1 安装软件 控制端和客户端都安装 https://sunlogin.oray.com/personal/download/ 2 再两台电脑上都安装好客户端和控制端后,打开控制端软件 可以看到自己登录 ...