1,為什么自己寫一個代碼生成器?
這個上一篇文章《Sqlsugar基本搭建》中已經講過了,因為一些代碼生成器對Oracle不友好,Oracle是全大寫。生成出來的model,就全部大寫了。這個看着非常蛋疼,
所以萌生了自己寫個代碼生成器的想法。
除此之外,還有一個原因,我們知道代碼生成器普遍的只生成model,當前也有些代碼生成器支持自己寫模板比如T4,CodeSmith等。
但是很少有代碼生成器 去生成表單,因為這個就純屬定制化了,雖然也可以通過寫模板搞定,但是多數情況下來說,不是自己的代碼生成器,不好改動。
也有人會說,現在都不用生成前端了,有像WTM 這樣的框架只要配置就好了。 還有人會說,還生成什么前端呀,現在前端都組件化了,Vue,寫好組件
到處引用就行了。我只能說,大家說的都沒錯!各花入各眼。 但是做為一個程序員,不是應該自己嘗試去擁有一個自己的代碼生成器嗎? 就算沒有代碼生成器,也應該去寫一下
代碼生成器的模板吧!?
話不多說,先上圖:
代碼生成器,是用Core 寫的,之前的文章有說過core 性能非常好,但是這里我鄭重提示一下:Winform 和 WPF 目前不要用core, (core 3.1)
微軟現在還沒來得及,把winform 和 wpf 的設計器搞好,之前更慘,之前連設計器都沒有有。現在設計器也莫名其妙卡頓。
2, 說說代碼生成器 引擎。
一開始代碼生成器,我也想直接用T4模板,但是搜遍了百度,卻沒有文章把講怎么把T4引擎 打到winform里面的,都是講怎么在vs里面用T4,所以這里放棄了T4,
后來在朋友的推薦下,看一下Velocity,看了下也不很不錯,剛准備上手,想着在幾個.net 群里問一下,結果發現大家都是用Razor 引擎,我擦,我還沒想到Razor,
還能干這個。。。 相比之下,Velocity還需要花時間熟悉, Razor 我熟啊。 asp.net mvc 不天天用嗎···!
果斷的用Razor! 這里發一下Razor 引擎的語法:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/razor?view=aspnetcore-3.1
就算不懂的,上手也非常快,簡單看一下,就可以自己寫模板了。
使用Razor 引擎,也能讓我這代碼生成器 的受眾群體 增加一些,東西做出來嘛,就是給人用的!
3,怎么寫模板。
所有的代碼生成器,一個基本的原則都是 關鍵字替換, 但是有了引擎的加持,我們就可以 使用 編程語言,比如 for,if 這些。
我貼一個最簡單 的model 實體生成 的模板代碼:
using System; using System.Linq; using System.Text; using SqlSugar; namespace @ViewBag.NameSpace { /// <summary> /// @Model.Comment ///</summary> public class @Model.Name { public @(Model.Name)() { } @foreach (var item in @Model.Columns) { @:///<summary> @:///描述:@(item.Comment) @:///</summary> @:public @item.PrimativeTypeName @item.CaseCamelName { get; set; } } } }
簡單的說一下,這里面的替換的內容都是哪來的,比如:
@ViewBag.NameSpace
viewBag,就不多說了,熟悉asp.net mvc 的朋友都知道,一般在控制寫寫ViewBig ,前端就可以獲取的到,這里也一樣
ViewBag ,是我在執行代碼生成 之前加的:
上面看到,我在viewbag里面 還加了一個時間,不過我模板里面沒有用到,一般有些人會加自己的 名字,聯系方式什么的,
都可以通過viewbag 去加。
至於其他的內容則來自數據庫,比如字段信息,表名,主外鍵,等等。。
大體來說分成兩個部分,一個是表信息,一個是字段信息, 如下:
這是表信息:
public interface ITableSchema { /// <summary> /// 表名 /// </summary> string Name { get; set; } /// <summary> /// 表備注 /// </summary> string Comment { get; set; } /// <summary> /// 列名 /// </summary> List<IColumn> Columns { get; set; } /// <summary> /// 外鍵集合 /// </summary> List<ForeignKey> ForiegnKeys { get; set; } /// <summary> /// 唯一鍵集合 /// </summary> List<UniqueKey> UniqueKeys { get; set; } /// <summary> /// 主鍵 /// </summary> PrimaryKey PrimaryKey { get; set; } /// <summary> /// 對象類型,TABLE or VIEW /// </summary> string ObjectType { get; set; } /// <summary> /// 視圖腳本 /// </summary> string ViewScript { get; set; } }
我們就可以在模板里面取這些信息,比如:
@Model.Name 表名
@Model.Comment 表備注
其他的以此類推,至於為什么是Model點出來的,因為是把整個對象扔進去了,對象在Razor里面就是Model這個變量。
字段信息,就很好理解了,就在 List<IColumn> Columns { get; set; } 里面,遍歷它就可以了
using System; using System.Collections.Generic; using System.Text; namespace SugarWinner.CodeGenerator.Facade.Interfaces { /// <summary> /// 數據列接口 /// </summary> public interface IColumn { /// <summary> /// 列名 /// </summary> string Name { get; set; } /// <summary> /// 列數據長度 /// </summary> int Length { get; set; } /// <summary> /// 列精度 /// </summary> int Scale { get; set; } /// <summary> /// 數據庫類型【char,number...等等】 /// </summary> string DbType { get; set; } /// <summary> /// 數據庫類型轉換為Csharp類型 /// </summary> Type CsharpType { get; set; } /// <summary> /// 轉換為基元類型 /// </summary> string PrimativeTypeName { get; set; } /// <summary> /// 列默認值 /// </summary> string DefaultValue { get; set; } /// <summary> /// 列描述 /// </summary> string Comment { get; set; } /// <summary> /// 是否可空 /// </summary> bool IsNullable { get; set; } /// <summary> /// 是否為數字類型 /// </summary> bool IsNumeric { get; set; } /// <summary> /// 是否自動增長 /// </summary> bool IsAutoIncrement { get; set; } /// <summary> /// 列所屬表 /// </summary> ITableSchema Table { get; set; } /// <summary> /// 駝峰命名 /// </summary> string CaseCamelName { get; set; } } }
前面有說,關於一些代碼生成器Oracle 全大寫,生成出來的字段就全大寫了,所以我這里特地加了駝峰命名法,解決了Oracle 數據庫的問題。
另外,要特別鳴謝Jason, 基本整個代碼生成器的 實體類,以及工廠,我都是從他的代碼生成器Copy出來的,實話jason的代碼命名還是取的非常不錯的。
說到這里,代碼生成器 是一個工廠模式,不熟悉工廠模式的就建議先熟悉一下工廠,再去修改代碼。
最后,目前代碼生成器 只支持,Oracle,SqlServer,MySql. 雖然我上面有 Sqlite 類型,但是 我並沒有去實現Sqlite。暫時沒有時間去搞這個,后面有時間
后面弄吧,或者 有好心人士,幫我弄一下,可以發我郵箱我合並進去: 274733956@qq.com
最后,最后。貼一下代碼連接:https://github.com/demon28/SugarWinner.CodeGenerator
整個手把手擼套框架,有了代碼生成器,算是真正意義上的開始。 希望通過6個月的時間,能把 目錄 里所有的條碼填完。