FreeSql.Generator命令行代碼生成器是如何實現的

来源:https://www.cnblogs.com/igeekfan/archive/2020/06/23/freesql-generator.html
-Advertisement-
Play Games

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


目錄

  • 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 命令行

怎麼使用呢。

  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://pic.downk.cc/item/5ef1c55614195aa5940207cf.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 = col => {
    if (col.CsType == typeof(string)) return " = string.Empty;";
    return "";
};
}
//xxx
namespace @gen.NameSpace {

@if (string.IsNullOrEmpty(gen.table.Comment) == false) {
	@:/// <summary>
	@:/// @gen.table.Comment.Replace("\r\n", "\n").Replace("\n", "\r\n		/// ")
	@:/// </summary>
}
	[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) {
		@:/// <summary>
		@:/// @col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n		/// ")
		@:/// </summary>
		}
		@:@("[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端及更多),輸出(生成文件)。

源碼解析

首先這是一個控制台應用,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的開發者,也能使用此工具,你只需要修改對應的模板即可。

使用方式:不多介紹。

FreeSql官方群 4336577

預覽圖


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • from:https://www.ghostscript.com/download/gsdnld.html https://www.codeproject.com/Articles/317700/Convert-a-PDF-into-a-series-of-images-using-Csharp h ...
  • 基於角色的訪問控制 (RBAC) 是將系統訪問限製為授權用戶的一種方法,是圍繞角色和特權定義的與策略無關的訪問控制機制,RBAC的組件使執行用戶分配變得很簡單。 在組織內部,將為各種職務創建角色。執行某些操作的許可權已分配給特定角色。成員或職員(或其他系統用戶)被分配了特定角色,並且通過這些角色分配獲 ...
  • 剛開始學習VBA的時候,保存自定義數據用的隱藏工作表;後來學了VSTO,把自定義數據保存到XML文件中;最近繼續深入學習,發現可以直接在xlsx文件中保存自定義數據,這裡就列出使用方法。 除了以上幾種保存方式,還可以保存為JSON格式,或者直接在xlsx文件中寫入xml。各種方式都有適合的應用場景, ...
  • 用好數據映射,MongoDB via Dotnet Core開發變會成一件超級快樂的事。 一、前言 MongoDB這幾年已經成為NoSQL的頭部資料庫。 由於MongoDB free schema的特性,使得它在互聯網應用方面優於常規資料庫,成為了相當一部分大廠的主數據選擇;而它的快速佈署和開發簡單 ...
  • // A delegate type for hooking up change notifications. public delegate void ProgressChangingEventHandler(object sender, string e); /// <summary> /// ...
  • 概念介紹: 單鏈表是一種鏈式存取的數據結構,用一組地址任意的存儲單元存放線性表中的數據元素。 鏈表中的數據是以結點來表示的,每個結點的構成:元素(數據元素的映象) + 指針(指示後繼元素存儲位置),元素就是存儲數據的存儲單元,指針就是連接每個結點的地址數據 由圖可知: 鏈表在進行添加/刪除時,只需要 ...
  • .NET 人臉識別庫 ViewFaceCore 這是基於 SeetaFace6 人臉識別開發的 .NET 平臺下的人臉識別庫這是一個使用超簡單的人臉識別庫這是一個基於 .NET Standard 2.0 開發的庫這個庫已經發佈到 NuGet ,你可以一鍵集成到你的項目此項目可以免費商業使用 ⭐、開源 ...
  • 0. 前言 通過前兩篇我們實現瞭如何在Service層如何訪問數據,以及如何運用簡單的加密演算法對數據加密。這一篇我們將探索如何實現asp.net core的身份驗證。 1. 身份驗證 asp.net core的身份驗證有 JwtBearer和Cookie兩種常見的模式,在這一篇我們將啟用Cookie ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...