主頁 > .NET開發 > FreeSql.Generator命令列代碼生成器是如何實作的

FreeSql.Generator命令列代碼生成器是如何實作的

2020-09-11 17:23:40 .NET開發

目錄

  • FreeSql介紹
  • FreeSql.Generator
  • RazorEngine.NetCore
  • 原始碼決議
  • FreeSql.Tools

FreeSql

FreeSql 是功能強大的物件關系映射技術(O/RM),支持 .NETCore 2.1+ 或 .NETFramework 4.0+ 或 Xamarin,

有一個強大的ORM,也方便我們開發一個代碼生成器,

一般情況下,我們開發資料庫相關的應用,主要分為三種code first、db first、model first

我只用過前二種,

  • code first,代碼優先,資料庫都是根據物體類生成,所有的關系,可以是邏輯關聯,也可以是物理關聯,
  • DB First: 資料庫優先,直接設計表結構,用設計工具生成表,設計主鍵,外鍵、索引,關聯關系等,

當我們使用DB First時,設計好的資料庫,我們怎么生成一些物體類、通用的代碼、控制器、服務層、Dto呢,今天我來給大家介紹一下FreeSql專案中的一些工具,當然,不使用此ORM的小伙伴也能使用此工具,因為他是通用,

FreeSql.Generator 命令列方式

通過幾行命令,就可實作生成專案中通用的代碼結構,不需要復制一段代碼后修改,加快開發速度,減少重復勞動,少用一根頭發,

由于每個人的專案結構,代碼位置各不相同,對于ORM來說,不同的業務邏輯各不相同,所以該專案沒有相應的模板,相信使用過Razor的同學一定能實作自己的模板,

1-2年前,我和一個學長也寫過代碼生成器,這里分享一下當時做專案時的一些模板,https://github.com/i542873057/SJNScaffolding/tree/master/SJNScaffolding.RazorPage/Templates,該專案是基于 . NET Core+Razor Page,由于已離職,所以沒有繼續維護,這些模板都和ABP相關,當時提取了一些通用的功能,單表操作,可以直接生成前后端功能,只需要在word中按統一的格式寫好資料字典的檔案,直接復制到系統,即可根據空格,定義型別等方式決議欄位,

回到FreeSql.Generator 命令列

  • 對于此工具的使用可參考 https://github.com/dotnetcore/FreeSql/wiki/DbFirst
  • 原始碼位置 https://github.com/dotnetcore/FreeSql/tree/master/Extensions/FreeSql.Generator
  • 前提是本地安裝了.net core 3.1 的sdk.

怎么使用呢,

  1. 安裝 dotnet-tool 生成物體類
dotnet tool install -g FreeSql.Generator
  1. 新建目錄,在地址欄輸入 cmd 快速打開命令視窗,輸入命令:
FreeSql.Generator --help

我們可以看到

C:\Users\igeekfan\Desktop\code>FreeSql.Generator --help
        ____                   ____         __
       / __/  ____ ___  ___   / __/ ___ _  / /
      / _/   / __// -_)/ -_) _\ \  / _ `/ / /
     /_/    /_/   \__/ \__/ /___/  \_, / /_/
                                    /_/


  # Github # https://github.com/2881099/FreeSql v1.5.0

    使用 FreeSql 快速生成資料庫的物體類

    更新工具:dotnet tool update -g FreeSql.Generator


  # 快速開始 #

  > FreeSql.Generator -Razor 1 -NameOptions 0,0,0,0 -NameSpace MyProject -DB "MySql,Data Source=127.0.0.1;..."

     -Razor 1                  * 選擇模板:物體類+特性

     -Razor 2                  * 選擇模板:物體類+特性+導航屬性

     -Razor "d:\diy.cshtml"    * 自定義模板檔案

     -NameOptions              * 總共4個布林值,分別對應:
                               # 首字母大寫
                               # 首字母大寫,其他小寫
                               # 全部小寫
                               # 下劃線轉駝峰

     -NameSpace                * 命名空間

     -DB "MySql,Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=資料庫;Charset=utf8;SslMode=none;Max pool size=2"

     -DB "SqlServer,Data Source=.;Integrated Security=True;Initial Catalog=資料庫;Pooling=true;Max Pool Size=2"

     -DB "PostgreSQL,Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=資料庫;Pooling=true;Maximum Pool Size=2"

     -DB "Oracle,user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=2"

     -DB "Sqlite,Data Source=document.db"

     -DB "Dameng,server=127.0.0.1;port=5236;user id=2user;password=123456789;database=2user;poolsize=2"
                               Dameng 是國產達夢資料庫

     -Filter                   Table+View+StoreProcedure
                               默認生成:表+視圖+存盤程序
                               如果不想生成視圖和存盤程序 -Filter View+StoreProcedure

     -Match                    正則運算式,只生成匹配的表,如:dbo\.TB_.+

     -FileName                 檔案名,默認:{name}.cs

     -Output                   保存路徑,默認為當前 shell 所在目錄
                               推薦在物體類目錄創建 gen.bat,雙擊它重新所有物體類
  • 更新命令列
dotnet tool update -g FreeSql.Generator
  1. 這里lin-cms-dotnetcore這個專案來測驗,

https://img.uj5u.com/2020/09/11/55559111721421.jpg

  • 資料庫表名是下劃線,欄位也是下劃線方式,
  • -Razor 指定 第一個模板
  • -NameOptions 0,0,0,1 最后一個1,代表 下劃線轉駝峰,滿足C#命名規則
  • -NameSpace 指定了命名空間 LinCms.Core.Entities
  • -DB 就是資料庫的相關配置
  • mysql 本地地址 127.0.0.1 3306埠 用戶名 root 密碼123456 資料庫 lin-cms
  • -Match book 這樣就能只生成book,支持正則運算式,如 -Math lin_user 就會生成以lin_user開頭的表,如dbo.TB_.+,會生成以TB開頭的表,即只生成匹配的表
  1. 執行此命令,
FreeSql.Generator -Razor 1  -NameOptions 0,0,0,1 -NameSpace LinCms.Core.Entities -DB "MySql,Data Source=127.0.0.1;Port=3306;User ID=root;Password=123456;Initial Catalog=lincms;Charset=utf8;SslMode=none;Max pool size=2"

這時候代碼已經生成了

其中一個代碼 生成如下,這些類是partial ,熟悉C#的同學,應該知道,類的定義使用此關鍵字,我們能在不同的地方為該類擴展,以防止重新同步資料庫的結構時,丟失改動的欄位,

namespace LinCms.Core.Entities {

	[JsonObject(MemberSerialization.OptIn), Table(Name = "book")]
	public partial class Book {

		/// <summary>
		/// 主鍵Id
		/// </summary>
		[JsonProperty, Column(Name = "id", IsPrimary = true, IsIdentity = true)]
		public long Id { get; set; }

		[JsonProperty, Column(Name = "author", DbType = "varchar(20)")]
		public string Author { get; set; } = string.Empty;

		[JsonProperty, Column(Name = "image", DbType = "varchar(50)")]
		public string Image { get; set; } = string.Empty;

        //更多xxx
	}

}

  • 最終效果圖如下

此時會生成二個檔案 __重新生成.bat,下次重新點擊他就能重新生成物體類了,

FreeSql.Generator -Razor "__razor.cshtml.txt" -NameOptions 1,1,0,1 -NameSpace MyProject -DB "MySql,Data Source=127.0.0.1;Port=3306;User ID=root;Password=123456;Initial Catalog=lincms;Charset=utf8;SslMode=none;Max pool size=2" -FileName "{name}.cs"

上面的命令-Razor 指定了這個txt檔案 __razor.cshtml.txt

我們可以定義自己的模板,以生成符合自已業務的的代碼,從而實作快速開發,

我們可以看下模板中的檔案內容,他就是asp.net下的mvc 結構下的razor后端模板渲染,把這個.txt后綴去掉,就很明了了,對于asp.net mvc的razor,我們可以將控制器下方法的值替換掉cshtml中的值,這個程序是有一個類別庫在幫我們實作的,叫RazorEngine,不過那個是.net framework下的實踐,.NET Framework 下的RazorEngine代碼生成介紹

@using FreeSql.DatabaseModel;@{
var gen = Model as RazorModel;

Func<string, string> GetAttributeString = attr => {
	if (string.IsNullOrEmpty(attr)) return null;
	return string.Concat(", ", attr.Trim('[', ']'));
};
Func<DbColumnInfo, string> GetDefaultValue = https://www.cnblogs.com/igeekfan/p/col => {
    if (col.CsType == typeof(string)) return " = string.Empty;";
    return "";
};
}
//xxx
namespace @gen.NameSpace {

@if (string.IsNullOrEmpty(gen.table.Comment) == false) {
	@:/// 
	@:/// @gen.table.Comment.Replace("/r/n", "/n").Replace("/n", "/r/n		/// ")
	@:/// 
}
	[JsonObject(MemberSerialization.OptIn)@GetAttributeString(gen.GetTableAttribute())]
	public partial class @gen.GetCsName(gen.FullTableName) {

	@foreach (var col in gen.columns) {

		if (string.IsNullOrEmpty(col.Coment) == false) {
		@:/// 
		@:/// @col.Coment.Replace("/r/n", "/n").Replace("/n", "/r/n		/// ")
		@:/// 
		}
		@:@("[JsonProperty" + GetAttributeString(gen.GetColumnAttribute(col)) + "]")
		@:public @gen.GetCsType(col) @gen.GetCsName(col.Name) { get; set; }@GetDefaultValue(col)
@:
	}
	}
@gen.GetMySqlEnumSetDefine()
}

RazorEngine.NetCore

到了.NET Core時代,我看了下FreeSql.Generator用的這個類別庫RazorEngine.NetCore,實作動態操作cshtml,生成需要的文本,

Razor Engine是基于微軟Razor決議的模板引擎,它允許你使用Razor語法構建動態模板,你只需要使用Engine的靜態方法,Engine.Razor.RunCompile等,

創建一個控制臺應用,然后安裝包,

Install-Package RazorEngine.NetCore
using RazorEngine;
using RazorEngine.Templating; // For extension methods.


string template = "Hello @Model.Name, welcome to RazorEngine!";
var result = Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World" });

Console.WriteLine(result);
  • 輸出如下內容
Hello World, welcome to RazorEngine!

此處使用的RunCompile方法是擴展方法,您需要參考RazorEngine.Templating命名空間,

The "templateKey" 保持唯一值,比如使用guid值,字串,并且你可以根據此字串key重新運行快取的模板,

如果再次根據此key,可使用原本的模板,

var result = Engine.Razor.Run("templateKey", null, new { Name = "Max" });
  • 會輸出如下內容
Hello Max, welcome to RazorEngine!

上面中的RunCompile第三個引數,傳null,因為我們第四個引數使用的是匿名類,

根目錄創建一個HelloWord.cshtml,要選擇屬性,->如果較新則復制 內容,

Hello @Model.Name, welcome to RazorEngine!

控制臺如下代碼,

string templateFilePath = "HelloWorld.cshtml";
var templateFile = File.ReadAllText(templateFilePath);
string templateFileResult = Engine.Razor.RunCompile(templateFile, Guid.NewGuid().ToString(), null, new
{
    Name = "World"
});

Console.WriteLine(templateFileResult);
  • 控制臺輸出
Hello World, welcome to RazorEngine!
  • 使用強型別 CopyRightUserInfo.cs生成一個著作權所有
using System;
namespace OvOv.Razor
{
    public class CopyRightUserInfo
    {
        public string UserName { get; set; }
        public string EmailAddress { get; set; }
        public DateTime CreateTime { get; set; }
        public string FileRemark { get; set; }
    }

}

根目錄創建一個CopyRightTemplate.cshtml,要選擇屬性,->如果較新則復制 內容,

@{
    var gen = Model as OvOv.Razor.CopyRightUserInfo;
}
//=============================================================
// 創建人:            @gen.UserName
// 創建時間:          @gen.CreateTime
// 郵箱:             @gen.EmailAddress
//==============================================================

控制臺如下代碼,

string copyRightTemplatePath = "CopyRightTemplate.cshtml";
var copyRightTemplate = File.ReadAllText(copyRightTemplatePath);
string copyRightResult = Engine.Razor.RunCompile(copyRightTemplate, Guid.NewGuid().ToString(), typeof(CopyRightUserInfo), new CopyRightUserInfo
{
    CreateTime = DateTime.Now,
    EmailAddress = "[email protected]",
    UserName = "IGeekFan"
});
Console.WriteLine(copyRightResult);

Console.ReadKey();
  • 控制臺輸出
//=============================================================
// 創建人:            IGeekFan
// 創建時間:          2020/6/23 18:14:08
// 郵箱:             [email protected]
//==============================================================

全放到控制臺下,輸出如下結果,代碼生成器最重要的一點解決了,我們就能實作自己的代碼生成器,先構建自己的模板,實作輸入(命令列,WPF,WEB端及更多),輸出(生成檔案),

  • 以上原始碼已放到示例代碼中 https://github.com/luoyunchong/dotnetcore-examples/blob/master/aspnetcore-freesql/OvOv.Razor/Program.cs

原始碼決議

首先這是一個控制臺應用,Main(string[] args)可接收多個引數,

  1. 處理無引數,--help
  2. 處理args陣列,決議出所有的引數,如果沒有設定,則為默認值,(處理一些引數例外問題)最重要的是根據-Razor,選定對應的模板,
ArgsRazor=""//根據-Razor  1 不是2 還是模板的路徑,取出的模板文本值,
var razorId = Guid.NewGuid().ToString("N");
RazorEngine.Engine.Razor.Compile(ArgsRazor, razorId);
  1. 根據資料庫連接串,取出引數過濾后的表,視圖,存盤程序
  2. 回圈資料庫的表等,
  • model為模板中需要的資料
  • razorId與上文的razorId相同,
  • sw為生成后的文本保存的值,
var sw = new StringWriter();
var model = new RazorModel(fsql, ArgsNameSpace, ArgsNameOptions, tables, table);
RazorEngine.Engine.Razor.Run(razorId, sw, null, model);
  1. 將sw字串保存生成類.cs檔案(根據引數配置生成檔案名)
  2. 另外生成一個__重新生成.bat,__razor.cshtml.txt,方便后續用戶重新生成物體類,

FreeSql.Tools

這是 FreeSql 衍生出來的輔助工具包,內含生成器等功能;作者:mypeng1985 因為這個不兼容mac,linux,所以作者建議使用dotnet-tool 命令列工具生成物體類,從而支持MAC/Linux系統,對于不是使用FreeSql的開發者,也能使用此工具,你只需要修改對應的模板即可,

使用方式:不多介紹,

  • https://github.com/2881099/Freesql.tools
  • 分為WPF ,WinForm + DSkin 版本(套網頁)
  • 看了下代碼,底層生成代碼邏輯也是用的RazorEngine .NET Framework 下的RazorEngine代碼生成介紹

FreeSql官方群 4336577

預覽圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/6428.html

標籤:.NET Core

上一篇:Magicodes.IE在.NET Core中通過請求頭匯出多種格式檔案

下一篇:C# 人臉識別庫 0.1

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more