0%

[DotnetCore]ORM系列-SqlSugar:實體產生器

前情提要

筆者這邊已經寫了幾篇SqlSugar的介紹文章,筆者一開始就形容SqlSugarEFCoreDapper的完美融合體,結合兩個套件有的優點並極大化其效用,就像這篇的主題,SqlSugar有提供產生實體的相關API,筆者目標是加以包裝變成是一個dotnet tool,可以透過下指令的方式完成產生實體作業。

內容

要做成dotnet tool,需要CommandLine相關函式,官方有提供System.CommandLine這個命名空間下,但筆者這邊使用的是將System.CommandLine往上包一層的套件CommandLineParser
只要於宣告物件上套上特定的Attribute即可生效,超方便使用。

建立專案

筆者這邊就使用dotnet cli來建立

1
2
3
dotnet new console -o Demo.Models.Generator
cd Demo.Models.Generator
code .

安裝套件

筆者這邊使用的是CommandLineParser

1
2
3
dotnet add package CommandLineParser
dotnet add package sqlsugarcore
dotnet add package MySqlConnector

Options物件宣告

接下來先製作Options物件,基本上就包含

  • 連線字串
  • 實體檔案放置位置
  • 實體物件的預設NameSpace
1
2
3
4
5
6
7
8
9
10
11
public class Options
{
[Option('c', "connectionstring", Required = true, HelpText = "資料庫連線字串")]
public string ConnectionString { get; set; }

[Option('p', "path", Required = true, HelpText = "Models檔案放置路徑")]
public string ModelPath { get; set; }

[Option('n', "namespace", Required = true, HelpText = "Model命名空間")]
public string ModelNameSpace { get; set; }
}

定義實作邏輯

筆者這邊就以參考的部落格中的教學文章一樣,宣告一個執行Command的實作邏輯,實作細節參考SqlSugar實體生成那一章節,一行就搞定,包含詳細的SqlSugar對應的Attribute已套上,非常的方便,不然自己手動一個一個宣告會很浪費時間,這也算是基礎建設的一環,最好是透過一行指令就能搞定最好。

筆者公司環境之前都使用EFCoreDapper混合使用的關係,實體部分透過EFCoreCli指令來完成,因為筆者環境都是使用DBFirst的方式,使用到的指令就是dotnet ef scaffold來完成生成實體作業,且筆者同事把這行指令用成batch檔案,每次要更新實體,只要點擊兩下即可完成。筆者的靈感來自於這裡,因此想要把SqlSugar的實體生成部份包裝成dotnet tool的形式來表現,使用一行指令即可完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static void Run(Options option)
{
//Console.WriteLine($"The value for --connectionstring is: {option.ConnectionString}");
//Console.WriteLine($"The value for --path is: {option.ModelPath}");
//Console.WriteLine($"The value for --namespace is: {option.ModelNameSpace}");
using var _db = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.SqlServer,
ConnectionString = option.ConnectionString,
InitKeyType = InitKeyType.Attribute,
IsAutoCloseConnection = true
});
_db.DbFirst.IsCreateAttribute().CreateClassFile(option.ModelPath, option.ModelNameSpace);
}

Main中呼叫

完整程式碼如下:

1
2
3
4
5
6
7
class Program
{
static void Main(string[] args)
{
Parser.Default.ParseArguments<Options>(args).WithParsed(Run);
}
}

命令列執行

筆者這邊就先以dotnet run來展示其效果

help說明效果

跟著筆者看一下Options宣告完後自動有help的說明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dotnet run -- --help
# 以下為輸出結果
Demo.Models.Generator 1.0.0
Copyright (C) 2021 Demo.Models.Generator

-c, --connectionstring Required. 資料庫連線字串

-p, --path Required. Models檔案放置路徑

-n, --namespace Required. Model命名空間

--help Display this help screen.

--version Display version information.

產生Model檔案指令

1
dotnet run -- -c "Server=localhost;Database=classicmodels;Uid=root;Pwd=\!QAZ2wsx" -p "/Users/eugenesu/Desktop/Desktop - Eugene’s MacBook Pro/Learning/Blog/DemoProjects/Demo.ORM/Demo.ORM.API/Models/SqlSugar" -n "Demo.ORM.Models.SqlSugar"

產生的Model檔案內容

透過指令產生之Model,已套上SqlSugar獨有的Attribute,利用DBFirst方式建立SqlSugar符合的資料庫對應物件如此簡單啊

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Linq;
using System.Text;
using SqlSugar;

namespace Demo.ORM.Models.SqlSugar
{
///<summary>
///
///</summary>
[SugarTable("customers")]
public partial class customers
{
public customers(){

}
/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(IsPrimaryKey=true)]
public int customerNumber {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string customerName {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string contactLastName {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string contactFirstName {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string phone {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string addressLine1 {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string addressLine2 {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string city {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string state {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public string postalCode {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:False
/// </summary>
public string country {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public int? salesRepEmployeeNumber {get;set;}

/// <summary>
/// Desc:
/// Default:
/// Nullable:True
/// </summary>
public decimal? creditLimit {get;set;}

}
}

結論

筆者這邊還尚欠一環,應該要將該專案包裝成nuget套件,並安裝於dotnet tool中,才可以真正的以dotnet tool的形式執行相關作業,筆者會再寫一篇說明,這篇就到這邊了,希望對你有幫助。

參考