在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. Dubbo多协议支持

    除了Dubbo服务暴露协议Dubbo协议外,Dubbo框架还支持另外8种服务暴露协议:RMI协议.Hessian协议.HTTP协议.WebService协议.Thrift协议.Memcached协议. ...

  2. 【Linux】【Shell】【Basic】条件测试和变量

    bash脚本编程       脚本文件格式:         第一行,顶格:#!/bin/bash         注释信息:#         代码注释:         缩进,适度添加空白行:   ...

  3. Docker从入门到精通(一)——初识

    1.Docker 是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容 ...

  4. 06 - Vue3 UI Framework - Dialog 组件

    做完按钮之后,我们应该了解了遮罩层的概念,接下来我们来做 Dialog 组件! 返回阅读列表点击 这里 需求分析 默认是不可见的,在用户触发某个动作后变为可见 自带白板卡片,分为上中下三个区域,分别放 ...

  5. pipeline 步骤

    目录 一.简介 二.文件相关 删除当前目录 切换到目录 判断文件是否存在 判断是否为类Unix 返回当前目录 将内容写入文件 读取文件内容 二.制品相关 存取临时文件 三.命令相关 script sh ...

  6. 一种基于Java Swing/HTML/MySQL的汽车租赁系统

    该项目是一个Java的课程作业(大二),主要运用Java.Swing.HTML.MySQL,实现基本的租车逻辑.界面可视化.信息导出.数据存储等功能.实现管理员.用户两种角色登录,并结合Java开发中 ...

  7. 分布式调用链跟踪工具Jaeger?两分钟极速体验

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. spring security oauth2搭建resource-server demo及token改造成JWT令牌

    我们在上文讲了如何在spring security的环境中搭建基于oauth2协议的认证中心demo:https://www.cnblogs.com/process-h/p/15688971.html ...

  9. CF205A Little Elephant and Rozdil 题解

    Content 有一头小象住在 \(\texttt{Rozdil}\) 小镇里,它想去其他的小镇旅行. 这个国家一共有 \(n\) 个小镇,第 \(i\) 个小镇距离 \(\texttt{Rozdil ...

  10. CF918B Radio Station 题解

    Content 有 \(n\) 个形如 \(a_i.b_i.c_i.d_i\) 的 IP 地址.有 \(m\) 条命令,每条命令由一条字符串 \(s\) 和一个形如 \(p.q.r.s\) 的 IP ...