在dbfrist 时代,用T4模板生成代码,貌似还没有感觉到别扭。但是到了codefrist 后,我想要实体生成生成备注,我就得想方设法的去把备注弄到数据库,然后 还要处理模型中类型像枚举这种属性,渐渐的感觉到了吃力。要不换种方式吧,想着去反射实体,但是用T4去处理这种反射,还是感觉到有点吃力,就觉得能不能直接像我们直接写后台程序一样去解析,后面想到了Razor 引擎,经过进一步的了解,发现大神封装了一个组件 RazorEngine.NetCore,他很好的解决了我的问题。
   下面就让我们来了解下这个组件吧,先让我们得到这个组件如图

有了组件,我们先去编写对应自己业务的模板先吧,就比如我这个我创建一个AddDto,我创建的模板如下:

@*@model LazyBoy.Dtos.DbTableDto*@
@using LazyBoy.Dtos;
@using LazyBoy.Extensions;
@using LazyBoy.Enums; using System;
using AutoMapper;
using Domain.Models.Enum;
using Domain.Models.Entitys;
using Sy.ExpressionBuilder.Modules;
using System.ComponentModel.DataAnnotations;
using Sy.ExpressionBuilder.Modules;
using Domain.Models.Entitys;
using AutoMapper;
using Domain.Models.Enum; namespace @GeneratorConfig.DtoNameSpaceName
{
/// <summary>
/// @Model.Remark
///</summary>
[AutoMap(typeof(@(@StringExtension.FirstToUp(@Model.TableName))), ReverseMap = true)]
public partial class BaseAdd@(@StringExtension.FirstToUp(@Model.TableName))Dto
{
@foreach (var pm in @Model.DbColumns)
{
@if ((pm.ColumnName.ToLower() != "id"&&(pm.PropertyType == EnumPropertyType.Field || pm.PropertyType == EnumPropertyType.Enum) ))
{ @:/// <summary>
@:/// @pm.Remark
@:/// </summary>
@:[Display(Name ="@(pm.Remark)")]
@if (pm.IsRequired)
{
@:[Required(ErrorMessage ="@(pm.Remark)不能为空")]
}
@if (pm.StringLengthMax!=0)
{
@:[StringLength(@(pm.StringLengthMax), MinimumLength =@(pm.StringLengthMin), ErrorMessage = "@(pm.Remark)的长度为{2}至{1}个字符")]
}
else if (pm.StringLengthMin!=0)
{
@:[StringLength(@(pm.StringLengthMin), ErrorMessage = "@(pm.Remark)的长度至少为{1}个字符")]
}
@if(pm.RangeMax!=null)
{
@:[Range(@(pm.RangeMax), MinimumLength =@(pm.RangeMin), ErrorMessage="@(pm.Remark)的范围在{1}至{2}之间")]
}
@if(pm.Regular!=null)
{
@:[RegularExpression("@(pm.Regular)", ErrorMessage = "@(pm.Remark)@(pm.ErrorMessage)")]
}
@:public virtual @pm.ColumnType @(pm.IsNullable==true?"?":"") @StringExtension.FirstToUp(pm.ColumnName) { get;set;} }
}
}
}

温馨提示,代码头部这个引用后台返回的实体的这个,我们编写的时候放出来,这样我们就可以像写Razor 视图一样了,后面生成代码的注释掉。

有了模板后,我们就可以生成我们要的AddDto了,在起始项(.net6 直接在Program) 添加并且编译我们的模板,如下:

            //打开并且读取模板
string template = File.ReadAllText(filePath); //CreateDto.cshtml
var nameKey = templateName.ToLower().Replace(".cshtml", "");
//添加模板
Engine.Razor.AddTemplate(nameKey, template);
//编译模板
Engine.Razor.Compile(nameKey, null);

然后我们根据反射拿到实体类库的解析类,传给引擎就好了

 var result = Engine.Razor.Run(templateName.ToLower(), null, item);
templateName.ToLower(),对应我们添加模板的key,item对应单个实体的解析类,下面给出我的示例代码:
 /// <summary>
/// 创建所有类型Dto
/// </summary>
/// <returns></returns>
[HttpGet]
public IResultModel CreateAllBaseDto()
{
CreateDtoManager dtoManager = new CreateDtoManager();
var dbTables = dtoManager.GetDbTable();
var dtoPath = _configuration.GetSection("DbConfigInfo")["CodeResourcePath"];
var templateNames = _configuration.GetSection("DbConfigInfo")["BaseDtoTemplateName"];
foreach (var item in dbTables)
{
foreach (var templateName in templateNames?.Split(',').ToList())
{
var result = Engine.Razor.Run(templateName.ToLower(), null, item);
var filePath = $"{dtoPath}/BaseDtos/{item.SchemaName.GetPath('_')}/{item.TableName}s";
var prefix = "";
if (templateName.Contains("add", StringComparison.OrdinalIgnoreCase))
prefix = "Add";
if (templateName.Contains("all", StringComparison.OrdinalIgnoreCase))
prefix = "All";
if (templateName.Contains("edit", StringComparison.OrdinalIgnoreCase))
prefix = "Edit";
string fileName = filePath + "\\" + $"{prefix}Base{item.TableName}Dto.cs"; //保存文件
FileHelper.Save(fileName, result);
}
}
return ResultTo.Success("生成成功");
}

让我们看看效果

然后保存在本地就大功告成了,我集中放到了一个文件夹,这样方便直接拷贝替换(集成到项目可以直接替换,但是有覆盖风险,没敢),后面看看最后的成果。

RazorEngine.NetCore 相见恨晚,它让我彻底放弃了T4模板的更多相关文章

  1. RazorEngine

    目标 使用razorengine编译cshtml页面生静态html 制作一个vs2017的插件,实现右击cshtml文件时,编译该文件. 环境 razorengine4.5 / netframewor ...

  2. RazorEngine.Templating MVC中View当模板

    最近在做一个生成JSON的功能,比较笨的办法就是把需要的数据拆分开,保存到数据库,在从数据库中取出来进行拼接.这种方法比较笨,代码就不贴了. 需要注意拼接的时的转义字符: "\"s ...

  3. 初识.netCore以及如何vs2019创建项目和发布

    一:什么是.netCore 从图上得知,.NetCore是同.NetFramework一样也是一种框架,并且都是基于.Net Standard Library,前面我们有用过.netFramwork来 ...

  4. NetCore的缓存使用详例

    关于我 作者博客|文章首发 缓存基础知识 缓存可以减少生成内容所需的工作,从而显著提高应用程序的性能和可伸缩性. 缓存最适用于不经常更改的 数据,生成 成本很高. 通过缓存,可以比从数据源返回的数据的 ...

  5. 模版引擎RazorEngine简介

    ASP.NET MVC的Razor想必大家都比较熟悉,这里介绍一个独立于ASP.NET的RazorEngine. RazorEngine是一个开源的项目,它的基础就是ASP.NET MVC的Razor ...

  6. X-Admin&ABP框架开发-代码生成器

    在日常开发中,有时会遇到一些相似的代码,甚至是只要CV一次,改几个名称,就可以实现功能了,而且总归起来,都可以由一些公用的页面更改而来,因此,结合我日常开发中使用到的页面,封装一个适合自己的代码生成器 ...

  7. 掘金 Android 文章精选合集

    掘金 Android 文章精选合集 掘金官方 关注 2017.07.10 16:42* 字数 175276 阅读 50053评论 13喜欢 669 用两张图告诉你,为什么你的 App 会卡顿? - A ...

  8. Asp.net Core 3.1 Razor视图模版动态渲染PDF

    Asp.net Core 3.1 Razor视图模版动态渲染PDF 前言 最近的线上项目受理回执接入了电子签章,老项目一直是html打印,但是接入的电子签章是仅仅对PDF电子签章,目前还没有Html电 ...

  9. FreeSql.Generator命令行代码生成器是如何实现的

    目录 FreeSql介绍 FreeSql.Generator RazorEngine.NetCore 源码解析 FreeSql.Tools FreeSql FreeSql 是功能强大的对象关系映射技术 ...

随机推荐

  1. System.exit(-1)和return 的区别

    对于只有一个单一方法的类或者系统来说是一样的,但是对于含有多个类和方法,且调用关系比较复杂时就不一样了. System.exit(-1)是指所有程序(方法,类等)停止,系统停止运行. return只是 ...

  2. 8.Vue.js-计算属性

    计算属性关键词: computed. 计算属性在处理一些复杂逻辑时是很有用的. 可以看下以下反转字符串的例子: <!DOCTYPE html><html><head> ...

  3. collection库更新1.4.0版本

    collection库更新1.4.0版本 collection库一直在使用中,周末集合github上的反馈以及contributor的修改,更新了1.4.0版本. 这个版本做了几个事情: 增加了三种类 ...

  4. idea开发环境搭建ssh

    idea2020完整web开发(struts2+spring+hibernate) idea破解 第一步: 下载最新的 IDEA 2020.3.2 版本安装包 https://www.jetbrain ...

  5. Table.SplitColumn拆分…Split…(Power Query 之 M 语言)

    数据源: 一列若干行数据. 目标: 根据特定条件拆分 操作过程: 选取"品名"列>[主页](或[转换])>[拆分列] 选取"品名"列>[主页] ...

  6. CF355B Vasya and Public Transport 题解

    Content 小 \(A\) 要乘坐交通工具,其中公交车的辆数是 \(n\),第 \(i\) 辆公交车的编号为 \(i\),乘坐次数为 \(a_i\):手推车的辆数是 \(m\),每辆手推车的编号为 ...

  7. LuoguB2013 温度表达转化 题解

    Content 输入华氏温度 \(F\),请将其转化为摄氏温度 \(C\),精确到小数点后 \(5\) 位. 数据范围:\(F\geqslant -459.67\). Solution 简单的输入输出 ...

  8. CF1440A Buy the String 题解

    Content 有 \(t\) 组询问,每组询问给出一个长度为 \(n\) 的 \(0/1\) 串,你可以花 \(h\) 的代价把 \(0\) 修改成 \(1\) 或者把 \(1\) 修改成 \(0\ ...

  9. Python软件目录结构

    目录组织方式 关于如何组织一个较好的Python工程目录结构,已经有一些得到了共识的目录结构.在Stackoverflow的这个问题上,能看到大家对Python目录结构的讨论. 这里面说的已经很好了, ...

  10. .net 程序通过 crontab 无法启动,手动执行脚本可以启动

    一.问题描述 .net 网关程序需要设置定时重启,按照日常操作先把正在运行的 PID kill 掉后,再执行启动服务. 把脚本放到 crontab 计划任务上,可以把服务 PID kill 掉,但无法 ...