c# 使用T4模板生成實體類(sqlserver)

来源:https://www.cnblogs.com/peterzhang123/archive/2020/01/02/12134570.html
-Advertisement-
Play Games

新建類庫,右鍵添加 "文本模板" 添加完成之後生成如下尾碼為 tt的文件: 雙擊文件:TextTemplate_Test.tt 文件打開,替換代碼如下 需要更換幾個配置的地方: 1,設置資料庫連接,找到該段代碼:string connectionString ="Data Source=127.0. ...


新建類庫,右鍵添加 "文本模板"

添加完成之後生成如下尾碼為 tt的文件:

 

 雙擊文件:TextTemplate_Test.tt 文件打開,替換代碼如下

 1 <#@ template debug="false" hostspecific="true" language="C#" #>
 2 <#@ assembly name="System.Core" #>
 3 <#@ assembly name="System.Data" #>
 4 <#@ assembly name="System.xml" #>
 5 <#@ import namespace="System.Linq" #>
 6 <#@ import namespace="System.Text" #>
 7 <#@ import namespace="System.Collections.Generic" #>
 8 <#@ import namespace="System.Data.SqlClient" #>
 9 <#@ import namespace="System.Data" #>
10 <#@ include file="ModelAuto.ttinclude"#>
11 <#@ output extension=".cs" #>
12 
13 <# var manager = new Manager(Host, GenerationEnvironment, true) { OutputPath = Path.GetDirectoryName(Host.TemplateFile)}; #>
14 <# 
15     //資料庫連接
16     string connectionString ="Data Source=127.0.0.1;Initial Catalog=TestDB;User ID=sa;Password=123456;"; 
17     SqlConnection conn = new SqlConnection(connectionString); 
18     conn.Open(); 
19     //查詢表
20     System.Data.DataTable schema = conn.GetSchema("TABLES"); 
21     string selectQuery = "select * from @tableName";   //查詢表語句
22     SqlCommand command = new SqlCommand(selectQuery,conn); 
23     SqlDataAdapter ad = new SqlDataAdapter(command); 
24     System.Data.DataSet ds = new DataSet();
25     //查詢欄位
26     string propQuery = "SELECT 表名=sobj.name,欄位名=scol.name,欄位說明=sprop.[value] FROM syscolumns as scol inner join sys.sysobjects as sobj on scol.id=sobj.id and sobj.xtype='U' and sobj.name<>'dtproperties' left join sys.extended_properties as sprop on scol.id=sprop.major_id and scol.colid=sprop.minor_id where sobj.name='@tableName' and scol.name='@columnName'"; 
27     SqlCommand command2 = new SqlCommand(propQuery,conn); 
28     SqlDataAdapter ad2 = new SqlDataAdapter(command2); 
29     System.Data.DataSet ds2 = new DataSet();
30  #>
31 
32 <# foreach(System.Data.DataRow row in schema.Rows) { #>
33 <# manager.StartBlock(row["TABLE_NAME"].ToString()+".cs"); #>
34 using System;
35 
36 namespace Entity.Model
37 {
38     /// <summary>
39     /// 實體類:<#= row["TABLE_NAME"].ToString() #> 
40     /// </summary>
41     [Serializable]
42     public class <#= row["TABLE_NAME"].ToString() #>
43     {
44         <# 
45         ds.Tables.Clear();
46         command.CommandText = selectQuery.Replace("@tableName","["+row["TABLE_NAME"].ToString()+"]"); 
47         ad.FillSchema(ds, SchemaType.Mapped, row["TABLE_NAME"].ToString());
48         foreach (DataColumn dc in ds.Tables[0].Columns)
49         { 
50         #>
51             <# 
52             ds2.Tables.Clear();
53             command2.CommandText = propQuery.Replace("@tableName",row["TABLE_NAME"].ToString()); 
54             command2.CommandText = command2.CommandText.Replace("@columnName",dc.ColumnName); 
55             ad2.Fill(ds2);
56             #>
57 
58         ///<summary>
59         ///<#= manager.TransFromSqlType(dc.DataType.Name) #>:<#=ds2.Tables[0].Rows[0].ItemArray[2]#>
60         ///</summary>
61         public <#= manager.TransFromSqlType(dc.DataType.Name) #> <#= dc.ColumnName #> { get; set; }  
62         <#}#>    
63     }
64 }
65 
66 <# manager.EndBlock(); #>
67 
68 <#}#>
69 
70 <#manager.Process(true);#>

需要更換幾個配置的地方:

1,設置資料庫連接,找到該段代碼:string connectionString ="Data Source=127.0.0.1;Initial Catalog=TestDB;User ID=sa;Password=123456;";  替換你要連接的資料庫即可;

2,設置命名空間,找到代碼:namespace Entity.Model {....} ,將該處的命名空間替換你要的即可;

3,相同目錄下添加代碼自動生成邏輯文件,文件名字為:ModelAuto.ttinclude

文件內容如下,

  1 <#@ assembly name="System.Core"#>
  2 <#@ assembly name="EnvDTE"#>
  3 <#@ import namespace="System.Collections.Generic"#>
  4 <#@ import namespace="System.IO"#>
  5 <#@ import namespace="System.Text"#>
  6 <#@ import namespace="Microsoft.VisualStudio.TextTemplating"#>
  7 
  8 <#+
  9 
 10 class Manager
 11 {
 12     public struct Block {
 13         public String Name;
 14         public int Start, Length;
 15     }
 16 
 17     public List<Block> blocks = new List<Block>();
 18     public Block currentBlock;
 19     public Block footerBlock = new Block();
 20     public Block headerBlock = new Block();
 21     public ITextTemplatingEngineHost host;
 22     public ManagementStrategy strategy;
 23     public StringBuilder template;
 24     public String OutputPath { get; set; }
 25 
 26     public Manager(ITextTemplatingEngineHost host, StringBuilder template, bool commonHeader) {
 27         this.host = host;
 28         this.template = template;
 29         OutputPath = String.Empty;
 30         strategy = ManagementStrategy.Create(host);
 31     }
 32 
 33     public void StartBlock(String name) {
 34         currentBlock = new Block { Name = name, Start = template.Length };
 35     }
 36 
 37     public void StartFooter() {
 38         footerBlock.Start = template.Length;
 39     }
 40 
 41     public void EndFooter() {
 42         footerBlock.Length = template.Length - footerBlock.Start;
 43     }
 44 
 45     public void StartHeader() {
 46         headerBlock.Start = template.Length;
 47     }
 48 
 49     public void EndHeader() {
 50         headerBlock.Length = template.Length - headerBlock.Start;
 51     }    
 52 
 53     public void EndBlock() {
 54         currentBlock.Length = template.Length - currentBlock.Start;
 55         blocks.Add(currentBlock);
 56     }
 57 
 58     public void Process(bool split) {
 59         String header = template.ToString(headerBlock.Start, headerBlock.Length);
 60         String footer = template.ToString(footerBlock.Start, footerBlock.Length);
 61         blocks.Reverse();
 62         foreach(Block block in blocks) {
 63             String fileName = Path.Combine(OutputPath, block.Name);
 64             if (split) {
 65                 String content = header + template.ToString(block.Start, block.Length) + footer;
 66                 strategy.CreateFile(fileName, content);
 67                 template.Remove(block.Start, block.Length);
 68             } else {
 69                 strategy.DeleteFile(fileName);
 70             }
 71         }
 72     }
 73 
 74         /// <summary>
 75         /// SQL[不完善,需要的自己改造]
 76         /// 更換欄位類型
 77         /// </summary>
 78         /// <param name="type"></param>
 79         /// <returns></returns>
 80         public string TransFromSqlType(string type)
 81         {
 82             if (string.IsNullOrEmpty(type))
 83             {
 84                 return string.Empty;
 85             }
 86             if (string.Equals(type, "Boolean", StringComparison.OrdinalIgnoreCase))
 87             {
 88                 return "bool";
 89             }
 90             else if (string.Equals(type, "Int32", StringComparison.OrdinalIgnoreCase))
 91             {
 92                 return "int";
 93             }
 94             else if (string.Equals(type, "Int64", StringComparison.OrdinalIgnoreCase))
 95             {
 96                 return "long";
 97             }
 98             else if (string.Equals(type, "String", StringComparison.OrdinalIgnoreCase))
 99             {
100                 return "string";
101             }
102             else if(string.Equals(type, "Byte", StringComparison.OrdinalIgnoreCase))
103             {
104                 return "byte";
105             }
106             else if (string.Equals(type, "Decimal", StringComparison.OrdinalIgnoreCase))
107             {
108                 return "decimal";
109             }
110             else if (string.Equals(type, "datetime", StringComparison.OrdinalIgnoreCase))
111             {
112                 return "DateTime";
113             }
114             return "string";
115         }
116 
117 }
118 
119 class ManagementStrategy
120 {
121     internal static ManagementStrategy Create(ITextTemplatingEngineHost host) {
122         return (host is IServiceProvider) ? new VSManagementStrategy(host) : new ManagementStrategy(host);
123     }
124 
125     internal ManagementStrategy(ITextTemplatingEngineHost host) { }
126 
127     internal virtual void CreateFile(String fileName, String content) {
128         File.WriteAllText(fileName, content);
129     }
130 
131     internal virtual void DeleteFile(String fileName) {
132         if (File.Exists(fileName))
133             File.Delete(fileName);
134     }
135 }
136 
137 class VSManagementStrategy : ManagementStrategy
138 {
139     private EnvDTE.ProjectItem templateProjectItem;
140 
141     internal VSManagementStrategy(ITextTemplatingEngineHost host) : base(host) {
142         IServiceProvider hostServiceProvider = (IServiceProvider)host;
143         if (hostServiceProvider == null)
144             throw new ArgumentNullException("Could not obtain hostServiceProvider");
145 
146         EnvDTE.DTE dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
147         if (dte == null)
148             throw new ArgumentNullException("Could not obtain DTE from host");
149 
150         templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
151     }
152 
153     internal override void CreateFile(String fileName, String content) {
154         base.CreateFile(fileName, content);
155         ((EventHandler)delegate { templateProjectItem.ProjectItems.AddFromFile(fileName); }).BeginInvoke(null, null, null, null);
156     }
157 
158     internal override void DeleteFile(String fileName) {
159         ((EventHandler)delegate { FindAndDeleteFile(fileName); }).BeginInvoke(null, null, null, null);
160     }
161 
162     private void FindAndDeleteFile(String fileName) {
163         foreach(EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) {
164             if (projectItem.get_FileNames(0) == fileName) {
165                 projectItem.Delete();
166                 return;
167             }
168         }
169     }
170 }#>

接下來就是見證奇跡的時刻,選中 TextTemplate_Test.tt 文件 按 Ctrl+C即可(每次更新實體類時,需要先修改一下模板文件,隨便修改什麼地方,按個空格也可以),生成模板代碼如下:

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 有時必須從幾個類中派生出一個子類,繼承它們所以的屬性和方法。但是java不支持多重繼承。有了介面,就可以得到多重繼承的效果。 介面是抽象方法和常量的定義的集合。 從本質上講,介面是一種特殊的抽象類,這種抽象類中只包含常量和方法的定義,而沒有變數和方法的實現。 實現介面類:class SubClass ...
  • 本文主要介紹瞭如何使用Docker構建PHP的開發環境,文中作者也探討了構建基於Docker的開發環境應該使用單容器還是多容器,各有什麼利弊。推薦PHP開發者閱讀。希望對大家有所幫助。 環境部署一直是一個很大的問題,無論是開發環境還是生產環境,但是 Docker 將開發環境和生產環境以輕量級方式打包 ...
  • redis redis在linux的安裝 redis常用命令 redis的數據類型 命令練習 基礎命令 strings類型數據相關命令 hashes哈徐數據相關命令 lists列表相關命令 sets集合相關命令 sorted sets有序集合相關命令 排行榜,zreverange 倒敘 zrange ...
  • 自從20世紀90年代初Python語言誕生至今,它已被廣泛應用於系統管理任務的處理和Web編程。今天就來給大家看看學Python的五大優勢吧! NO.1 全球三大主流編程語言之一 python是一種面向對象的解釋型電腦程式設計語言,具有豐富和強大的庫。它已經成為繼Java、C++之後的第三大語言, ...
  • HashSet、 LinkedHashSet、TreeSet之間的區別 步驟 1 : HashSet LinkedHashSet TreeSet HashSet: 無序 LinkedHashSet: 按照插入順序 TreeSet: 從小到大排序 package collection; import ...
  • 請看代碼: //1、null。 //int i1 = (int)null;//編譯時報錯:無法將“null”轉換為“int”,因為後者是不可以為“null”的值類型。 //int i2 = int.Parse(null);//執行時報錯:“System.ArgumentNullException”, ...
  • 在上面幾篇文章的學習之後,組織管理的新增功能的前端與後臺功能基本實現了我們所要。今天開始我們要通過WebAPI來替換控制器中的操作方法。在學習WebAPI之前,我先來介紹一下Swagger這個組件。 ...
  • 從何說起 這來自於我把項目遷移到Asp.Net Core的過程中碰到一個問題。在一個web程式中同時包含了MVC和WebAPI,現在需要給WebAPI部分單獨添加一個介面驗證過濾器 ,常規做法一般是寫好過濾器後給需要的控制器掛上這個標簽,高級點的做法是註冊一個全局過濾器,這樣可以避免每次手動添加同時 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...